先來看看一道常見的面試題:
void isKindOfAndisMemeberOf() {
BOOL b1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL b2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL b3 = [(id)[Person class] isKindOfClass:[Person class]];
BOOL b4 = [(id)[Person class] isMemberOfClass:[Person class]];
BOOL b5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL b6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL b7 = [(id)[Person alloc] isKindOfClass:[Person class]];
BOOL b8 = [(id)[Person alloc] isKindOfClass:[Person class]];
NSLog(@"\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n%hhd\n",b1,b2,b3,b4,b5,b6,b7,b8);
}
要想知道輸出結(jié)果為什么,必須先知道isKindOfClass與isMemberOfClass的具體實(shí)現(xiàn)奇徒。
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
解析
-
+ (BOOL)isKindOfClass:(Class)cls
實(shí)現(xiàn)判斷元類是不是為當(dāng)前類,再判斷元類的父類是不是當(dāng)前類,依次判斷下去。所以:
-
NSObject
的元類為根元類
不同于NSObject
,根元類
的父類為NSObject
與NSObject
相同,所以b1
為true
。 -
Person
的元類為Person(元類)
不同,Person(元類)
的父類為根元類
不同,根元類
的父類為NSObject
不同,NSObject
父類為nil
不同,所以b3
為false
。
-
+ (BOOL)isMemberOfClass:(Class)cls
是去和元類
做比較,元類
與類
不同,所以b2
與b4
為false
才避。
3.- (BOOL)isKindOfClass:(Class)cls
與- (BOOL)isMemberOfClass:(Class)cls
,都是判斷實(shí)例對象的類是不是對應(yīng)的類,區(qū)別在于isKindOf會往父類找,所以b5
到b8
都為true
背零。