*Note that the implementation of NS{,Mutable}Array has changed since this answer was written. As a result, isKindOfClass:
now works. On what platforms where and when, I don't know.
Until it is documented as safe to do so, I would strongly recommend NOT writing code that tries to detect whether a collection is mutable or immutable. Even if it were safe, such a design pattern is almost always indicative of a serious design flaw.
(For those with access) Filed rdar://10355515 asking for clarification.
Consider:
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;
}
(I'm using non-empty arrays because an empty NSArray
is common enough that Cocoa offers a single shared instance as an optimization.)
array's class: NSCFArray
mutableArray's class: NSCFArray
array responds to addObject: YES
I.e. neither -isKindOfClass:
nor checking for implementation of addObject:
will work.
In short, you can't tell the difference between an NSArray and an NSMutableArray. This is by design and very much the intended behavior. It also holds true for NSString
, NSDictionary
and NSSet
(all of which have a mutable subclass).
That may come as a surprise. The reality, though, is that design patterns that require checking for mutability are confusing to use and incur significant overhead.
For example, if test-for-mutability were a common pattern than all of the methods in Cocoa that return NSArray
instances would have to actually return NSArray
instances and never return a reference to the internal NSMutableArray
that might be being used.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…