NSDate isMemberOfClass: [NSDate class] returns fal

2019-07-18 11:52发布

问题:

This question already has an answer here:

  • usage of isMemberOfClass; returning false 3 answers

this is bizarre. The following if statement is failing. What could be wrong?

 NSDate *date = [NSDate date];

 if ([date isMemberOfClass: [NSDate class]]) {
    // Not executed.
 }

回答1:

It happens that classes like NSArray, NSDictionary, NSString and NSData are class clusters. This concept is explained better in the documentation, and it means that you will not get a direct instance for that class.

Due to the variety of "data" to be handled, the class has internal specialised subclasses; and when you create an instance it will be determined which of these internal subclasses is the best option, and your object will then be an instance of that subclass (not of NSData itself).

In this case, if you need to check that, use isKindOfClass: which will be true for subclasses as well.

NSDate *date = [NSDate date];

if ([date isKindOfClass: [NSDate class]]) {
    /* ... */
}

Edit: Just as an additional example, calling NSStringFromClass([obj class]) in these objects:

NSData   * data     = [NSData data];
NSData   * str_data = [@"string" dataUsingEncoding:NSUTF8StringEncoding];
NSNumber * n_bool   = [NSNumber numberWithBool:YES];
NSNumber * n_int    = [NSNumber numberWithInt:42];
NSArray  * array    = [NSArray array];

Results in:

_NSZeroData
NSConcreteMutableData
__NSCFBoolean
__NSCFNumber
__NSArrayI


回答2:

NSDate is a class cluster.

That means when you try to do that underneath it's different class (concrete implementation of NSDate) :)

More on class clusters here