isMemberOfClass - 調用者必須是傳入的類的實例對象才返回YES- 判斷調用者是否是傳入對象的實例,別弄反了,如 [s1 isMemberOfClass:p1] ,意思是s1是否是p1的實例對象- 去去父類遞歸查找判斷 源碼: 有兩個方法,一個類方法,一個對象方法,兩者區別: - 實例 ...
isMemberOfClass
- 調用者必須是傳入的類的實例對象才返回YES
- 判斷調用者是否是傳入對象的實例,別弄反了,如 [s1 isMemberOfClass:p1] ,意思是s1是否是p1的實例對象
- 去去父類遞歸查找判斷
源碼:
+ (BOOL)isMemberOfClass:(Class)cls { return object_getClass((id)self) == cls; } - (BOOL)isMemberOfClass:(Class)cls { return [self class] == cls; }
有兩個方法,一個實例方法,一個類方法,兩者區別:
- 實例方法:是根據實例對象取得類對象,再去判斷
- 類方法:是根據對象取得元類對象,再去判斷
實例代碼:
XPerson* p1 = [[XPerson alloc]init]; XStudent* s1 = [[XStudent alloc]init]; // true (用s1的類對象和 [s1 class] 判斷,肯定是一樣的了) NSLog(@"s1是否是s1 實例: %i",[s1 isMemberOfClass:[s1 class]]); // true ([s1 class] 與 [XStudent class] 等同,一個類只會有一個類對象,一個元類對象,可以有多個實例對象) NSLog(@"s1是否是XStudent 實例: %i",[s1 isMemberOfClass:[XStudent class]]); // false (s1的類對象 != p1的類對象) NSLog(@"s1是否是p1 實例: %i",[s1 isMemberOfClass:[p1 class]]); // false (同上) NSLog(@"s1是否是XPerson 實例: %i",[s1 isMemberOfClass:[XPerson class]]); // false (XStudent元類對象 != XStudent類對象)(底層是獲取XStudent的元類去比較) NSLog(@"XStudent是否是XStudent 實例: %i",[XStudent isMemberOfClass:[XStudent class]]); // true (XStudent元類對象 = XStudent元類對象) NSLog(@"XStudent是否是XStudent元類 實例: %i",[XStudent isMemberOfClass:object_getClass([XStudent class])]); // false (XStudent元類對象 != XPerson元類對象) NSLog(@"XStudent是否是XPerson元類 實例: %i",[XStudent isMemberOfClass:
isKindOfClass
- 調用者是傳入的類的實例對象,或者調用者是傳入類的繼承者鏈中的類的實例對象,則返回YES
- 判斷調用者是否是傳入對象的子類,別弄反了
- 不進行父類遞歸去查找判斷
源碼:
+ (BOOL)isKindOfClass:(Class)cls { for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->super_class) { if(tcls == cls) return YES; } return NO; } -(BOOL)isKindOfClass:(Class)cls { for(Class tcls = [self class]; tcls; tcls = tcls->super_class) { if(tcls == cls) return YES; } return NO; }
實例代碼:
XPerson* p1 = [[XPerson alloc]init]; XStudent* s1 = [[XStudent alloc]init]; // true (用s1的類對象、父類類對象、基類類對象([NSObject class]) 去和 p1的類對象比較,[p1 class]是s1的父類類對象) NSLog(@"s1是否是p1 子類: %i",[s1 isKindOfClass:[p1 class]]); // true (同上:[XPerson class] 與 [p1 class]是等同的) NSLog(@"s1是否是XPerson 子類: %i",[s1 isKindOfClass:[XPerson class]]); // true ([NSObject class]是s1的基類類對象) NSLog(@"s1是否是NSObject 子類: %i",[s1 isKindOfClass:[NSObject class]]); // false (用 XStudent的元類、父元類、基類(NSObject類對象) 去與 XPerson的對象比較) NSLog(@"XStudent是否是XPerson 子類: %i",[XStudent isKindOfClass:[XPerson class]]); // true (類方法需要傳入 元類進去判斷,裡面會取 XStudent 元類去比較) NSLog(@"XStudent是否是XPerson元類 子類: %i",[XStudent isKindOfClass:object_getClass([XPerson class])]); // true (元類的最上層就是基元類) NSLog(@"XStudent是否是NSObject元類 子類: %i",[XStudent isKindOfClass:object_getClass([NSObject class])]);