Here\'s a small test program I wrote:
#import
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutorel
The -isMemberOfClass: is useful when you're implementing the -isEqual:
method in your own classes. If you have a class like this:
@interface Person : NSObject {
NSString *name;
NSUInteger age;
}
@property(copy) NSString *name;
@property(assign) NSUInteger age;
@end
And you want two Person objects to be deemed identical if they have the same name and age, you have to implement -isEqual:
, and the -hash
method from the NSObject
protocol:
- (BOOL)isEqual:(id)obj {
return [obj isMemberOfClass:[self class]]
&& [obj name] == self.name
&& [obj age] == self.age;
}
- (NSUInteger)hash {
return [self.name hash] + age;
}
PS: why use [obj isMemberOfClass:[self class]]
rather than simply [obj class] == [self class]
? It doesn't matter much in the code above, but it becomes important when you're dealing with more complex code that makes use of NSProxy
. The isMemberOfClass:
method will ask the object the proxy is standing in for if it is a member of that class, which is probably what you want.
You generally want isKindOfClass:
, not isMemberOfClass:
. The difference is that isKindOfClass:
will return YES
if the receiver is a member of a subclass of the class in question, whereas isMemberOfClass:
will return NO
in the same case.
As Graham Lee points out, NSArray
is a class cluster. That means that every NSArray
instance is actually an instance of some subclass—hence your findings. Only isKindOfClass:
is useful for class-membership testing with class clusters.
That said, you generally should use respondsToSelector:
rather than class-membership testing. One example would be objectEnumerator
, which is also implemented by NSSet
and NSDictionary
(both of those also being class clusters). An exception would be plist serialization: sets aren't property lists, so you'd need to send allObjects
to your set to get an array before trying to make plist data from it.
I've never used -isMemberOfClass: myself, because if I've added functionality to an existing class it's usually been through adding methods, so -respondsToSelector: has given me what I need. On the other hand I can see how wanting to know which specific class you're looking at (an instance of) may be useful. For instance if you're dealing with an NSConstantString or NSSimpleCString you may be more willing to make assumptions regarding -fastestEncoding than you might be with instances of other classes.
To answer the question in the body, yes you're correct. The NSArray is implemented as a class cluster, so you will not see an object which isMemberOfClass: [NSArray class]
. That doesn't make -isMemberOfClass: meaningless, it just means it's never true for NSArray.