首先我們先來看一段代碼:
@interface Person : NSObject
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"%@", [NSObject class]);
NSLog(@"%@", [Person class]);
BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [(id)[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [(id)[Sark class] isMemberOfClass:[Sark class]];
NSLog(@"%d--%d--%d--%d", res1, res2, res3, res4);
}
return 0;
}
輸入結(jié)果:
NSObject
Person
1-0-0-0
可能執(zhí)行結(jié)果出乎大多數(shù)人的意料,
如果不是很清楚對象恃锉、類對象搀菩、元類關(guān)系的,可以先看一下下圖:
對象破托、類對象肪跋、元類關(guān)系.png
- 對象的isa指針指向類對象
- 類對象的指針指向元類
//類對象返回自身
+ (Class)class {
return self;
}
[NSObject class]、[Person class]返回還是當(dāng)前類對象
下面可以看看兩個isMemberOfClass炼团、isKindOfClass內(nèi)部實(shí)現(xiàn)澎嚣,
//isMemberOfClass實(shí)現(xiàn)
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
isMemberOfClass比較兩個isa指向的類對象是否一樣。
能判斷對象是否是當(dāng)前類的實(shí)例對象.
//isKindOfClass實(shí)現(xiàn)
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
前者對象的(class)類對象是否與后者類對象相同瘟芝,如果相同返回YES
不相等的話就易桃,就繼續(xù)對象的類對象的superclass看是否相等,一直找到根類
一锌俱、 [(id)[NSObject class] isKindOfClass:[NSObject class]];
其實(shí)通過isKindOfClass內(nèi)部實(shí)現(xiàn)源碼晤郑,可以理解為:
- 前者[[NSObject class] class](NSObject的Meta Class)與后者[NSObject class](NSObject的class)是否相等
- 相等返回true
- 不相等的話,就遍歷NSObject的元類的superclass,看是否相等.
- 如上圖NSObject的元類的superclass指向NSObject的類對象,所以返回的true造寝。
二磕洪、[(id)[NSObject class] isMemberOfClass:[NSObject class]]
- isMemberOfClass只能判斷對象是否是當(dāng)前類的實(shí)例對象,NSObject的元類肯定不是NSObject類對象的實(shí)例诫龙。所以返回false析显。
三、[(id)[Person class] isKindOfClass:[Sark class]];
執(zhí)行流程大概是這樣:
- [[Person class]class] 執(zhí)行完之后調(diào)用 isKindOfClass签赃,
- 第一次 for 循環(huán)谷异,Person 的 Meta Class 與 [Person class] 不等,
- 第二次 for 循環(huán)锦聊,Person Meta Class 的 super class 指向的是 NSObject Meta Class歹嘹, 和 Person Class 不相等。
- 第三次 for 循環(huán)孔庭,NSObject Meta Class 的 super class 指向的是 NSObject Class尺上,和 Person Class 不相等。
- 第四次循環(huán)圆到,NSObject Class 的super class 指向 nil怎抛, 和 Person Class 不相等。第四次循環(huán)之后构资,退出循環(huán)抽诉,所以第三行的 res3 輸出為 NO。
四吐绵、[(id)[Sark class] isMemberOfClass:[Sark class]]
isa 指向 Person 的 Meta Class迹淌,和 Person Class 也不等。