关于使用
[object class] == [Object class]判断某个对象是否是某个类的实例时所需要注意的问题
该写法是否有效?
-
简单创建Person类
// .h @interface Person : NSObject @end // .m @implementation Person @end -
使用
Person打印验证[object class] == [Object class]的有效性Person *person = [[Person alloc] init]; NSLog(@"%@ - %p", [person class], [person class]); NSLog(@"%@ - %p", [Person class], [Person class]); BOOL result = [person class] == [Person class]; NSLog(@"%@", result ? @"YES" : @"NO"); -
得到打印:
Person - 0x1000020e0 Person - 0x1000020e0 YES
通过上面的验证,似乎[object class] == [Object class]确实可以用来判断某个对象是否是某个类的实例。但当我们不加思考就使用该写法时,会发生什么问题呢?让我们看看下面的例子:
-
使用
NSString打印验证[object class] == [Object class]的有效性NSString *string = @"string"; NSLog(@"%@ - %p", [string class], [string class]); NSLog(@"%@ - %p", [NSString class], [NSString class]); BOOL result = [string class] == [NSString class]; NSLog(@"%@", result ? @"YES" : @"NO"); -
猜猜打印?
__NSCFConstantString - 0x7fff8537b8e0 NSString - 0x7fff858f5178 NO此时我们可以观察到结果出现了不一致。为什么呢?
-
分析
读过《Effective Objective-C 2.0》(第九条)的小伙伴应该可以反应过来
__NSCFConstantString和NSString之间的关系——类簇。没错,在OC中通过某个类创建的实例不一定就是该类的实例,它也可能是某个被系统隐藏的类的实例。不止是NSString如此,NSArray等一系列容器类以及自定义的类簇也可能会发生该问题。 -
解决方案
如果意识到所判断的类内部可能是类簇的实现时,建议使用
[object isKindOfClass: [Object class]]来判断是否属于该类的继承体系。这里也不能使用
[object isMemberOfClass: [Object class]],因为该对象不是该类的直接实例。