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])]);