Ale*_*der 21 objective-c nsmutablearray nsarray ios
如何检查变量是NSArray还是NSMutableArray?
bbu*_*bum 32
*请注意,自编写此答案以来,NS {,Mutable}数组的实现已发生变化.结果,isKindOfClass:现在有效.什么平台何时何地,我不知道.
在记录为安全之前,我强烈建议不要编写试图检测集合是可变还是不可变的代码.即使它是安全的,这样的设计模式几乎总是表明严重的设计缺陷.
(对于那些有访问权限的人)提交rdar:// 10355515要求澄清.
考虑:
int main (int argc, const char * argv[]) {
NSArray *array = [NSArray arrayWithObjects: [NSObject new], nil];
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects: [NSObject new], nil];
NSLog(@"array's class: %@", NSStringFromClass([array class]));
NSLog(@"mutableArray's class: %@", NSStringFromClass([mutableArray class]));
NSLog(@"array responds to addObject: %@",
[array respondsToSelector: @selector(addObject:)] ? @"YES" : @"NO");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(我使用的是非空数组,因为空的NSArray很常见,Cocoa提供了一个共享实例作为优化.)
array's class: NSCFArray
mutableArray's class: NSCFArray
array responds to addObject: YES
Run Code Online (Sandbox Code Playgroud)
即既不-isKindOfClass:检查也不会检查addObject:是否有效.
简而言之,您无法区分NSArray和NSMutableArray之间的区别.这是设计和非常预期的行为.它也适用于NSString,NSDictionary并且NSSet(所有这些都具有可变子类).
这可能会让人感到惊讶.但实际情况是,需要检查可变性的设计模式使用起来很混乱,并且会产生很大的开销.
例如,如果test-for-mutability是一个常见模式,而不是Cocoa中的所有方法,则返回NSArray实例必须实际返回NSArray实例,并且永远不会返回对NSMutableArray可能正在使用的内部的引用.
不好但技术上准确的建议......
执行此操作的唯一方法是[unknownArray addObject:someObject]在@try/ @catchblock 内部调用并捕获NSInternalInconsistencyException将在unknownArray不可变时抛出的内容(实际异常可能是未实现的方法或类是不可变的异常).
好建议...
简短的回答是,永远不要试图在不可变对象内部查看它是否在内部是可变的.
隐藏不可变对象可变性的原因是支持类似于以下类的方法:
- (NSArray *)internalObjects
{
return myInternalObjects;
}
Run Code Online (Sandbox Code Playgroud)
该对象myInternalObjects可以是可变的,但是这个类的方法是说:不要改变我给你的东西.这样做可能会有严重的危险.如果类允许您更改数组,则它将具有不同的访问器或更改器方法.
如果你有一个需要对myInternalObjects变量进行可变访问的友元类,那么声明一个特殊的适配器类别,只有友元类使用类似的方法导入
- (NSMutableArray *)mutableInternalObjectsArray;
Run Code Online (Sandbox Code Playgroud)
这将允许朋友(您假设其足够聪明,不违反特殊规则)获得所需的访问权限,但不会在更广泛的意义上暴露可变性.
我会做以下的事情-
if([unkownArray isKindOfClass:[NSMutableArray class]]){
// This is a nsmutable array
}
else if ([unkownArray isKindOfClass:[NSArray class]]){
// This is a nsarray
}
Run Code Online (Sandbox Code Playgroud)
参见NSObject的-class方法:
NSLog(@"myUnknownArray is of type: %@", [myUnknownArray class]);
Run Code Online (Sandbox Code Playgroud)
您还可以通过以下方法更直接地检查+class:
BOOL isMutableArray = [myUnknownArray isKindOfClass:[NSMutableArray class]];
Run Code Online (Sandbox Code Playgroud)