精華Pod庫分享
一裂逐、類、根類泣栈、元類卜高、根元類關(guān)系圖
網(wǎng)上流傳一張類,元類南片,根元類的關(guān)系圖掺涛。詳細(xì)描述了它們相互間的繼承關(guān)系和isa指向關(guān)系。下面用代碼對(duì)這張圖進(jìn)行驗(yàn)證疼进。
二薪缆、驗(yàn)證關(guān)系
驗(yàn)證之前我們了解一下兩個(gè)runtime函數(shù)
- class_getSuperclass()
- 通過object_getClass獲取對(duì)象isa指針指向鏈。
object_getClass
參數(shù)是id類型伞广,它返回的是這個(gè)id的isa指針?biāo)赶虻腃lass拣帽,如果傳參是Class,則返回該Class的metaClass嚼锄。
- 通過object_getClass獲取對(duì)象isa指針指向鏈。
- object_getClass()
- 通過class_getSuperclass方法獲取對(duì)象的繼承鏈减拭。
class_getSuperclass
參數(shù)是Class類型,它返回的是該Class的superClass指針指向的Class区丑。
- 通過class_getSuperclass方法獲取對(duì)象的繼承鏈减拭。
Person 類繼承自NSObject
Person *p = [Person new];
Class class1 = object_getClass(p); // 獲取p ---> 類對(duì)象
Class class2 = [p class]; // 獲取p ---> 類對(duì)象
NSLog(@"class1 === %p class1Name == %@ class2 === %p class2Name == %@",class1,class1,class2,class2);
/** 元類查找過程 */
Class class3 = objc_getMetaClass(object_getClassName(p)); // 獲取p ---> 元類
NSLog(@"class3 == %p class3Name == %@",class3,class3);
Class class4 = objc_getMetaClass(object_getClassName(class3)); // 獲取class3 ---> 元類 此時(shí)的元類拧粪,class4就是根元類修陡。
NSLog(@"class4 == %p class4Name == %@",class4,class4); // class4 == 0x106defe78 class4Name == NSObject
/** 元類查找結(jié)束,至此可霎。我們都知道 根元類 的superClass指針是指向 根類對(duì)象 的魄鸦;根類對(duì)象的isa指針有指向根元類對(duì)象;根元類對(duì)象的isa指針指向根元類自己癣朗;根類對(duì)象的superClass指針指向nil */
Class class5 = class_getSuperclass(class1); // 獲取 類對(duì)象的父類對(duì)象
NSLog(@"class5 == %p class5Name == %@",class5,class5); //class5 == 0x106defec8 class5Name == NSObject
// 此時(shí)返現(xiàn)class5 已經(jīng)是NSObject号杏,我們?cè)俅潍@取class5的父類,驗(yàn)證class5是否是 根類對(duì)象
Class class6 = class_getSuperclass(class5); // 獲取 class5的父類對(duì)象
NSLog(@"class6 == %p class6Name == %@",class6,class6); // class6 == 0x0 class6Name == (null) 至此根類對(duì)象驗(yàn)證完畢斯棒。
/** 驗(yàn)證根類對(duì)象與根元類對(duì)象的關(guān)系 */
Class class7 = objc_getMetaClass(object_getClassName(class5)); // 獲取根類對(duì)象 對(duì)應(yīng)的 根元類 是否是class4 對(duì)應(yīng)的指針地址
NSLog(@"class7 == %p class7Name == %@",class7,class7); // class7 == 0x106defe78 class7Name == NSObject
Class class8 = class_getSuperclass(class4); // 獲取根元類class4 superClass 指針的指向 是否是根類對(duì)象class5 的指針地址
NSLog(@"class8 == %p class8Name == %@",class8,class8); // class8 == 0x106defec8 class8Name == NSObject; class8與class5指針地址相同
Class class9 = objc_getMetaClass(object_getClassName(class4)); // 獲取根元類 isa 指針是否是指向自己
NSLog(@"class9 == %p class9Name == %@",class9,class9); // class9 == 0x106defe78 class9Name == NSObject主经; class9 與 class4荣暮、class7指針地址相同
結(jié)果
由上運(yùn)行結(jié)果可知:
- 實(shí)例對(duì)象:p
- 類對(duì)象 :class1、class2
- 元類對(duì)象:class3
- 根元類 : class4罩驻、class7穗酥、calss9
- 根類對(duì)象:class5、calss8
總結(jié)圖
三惠遏、iOS中的 isKindOfClass 和 isMemberOfClass區(qū)別砾跃?
- 如下,Person繼承自NSObject节吮,[Person class]的地址抽高,就是Person實(shí)例的類對(duì)象地址。
Person *son = [Person new];
Class class1 = object_getClass(son);
NSLog(@"%p === %p ==== %p ==== %p",class1,[son class],[Person class],son);
打印結(jié)果:
2019-09-20 15:24:50.777969+0800 sortTime[3041:228435]
0x105248970 === 0x105248970 ==== 0x105248970 ==== 0x600001628930
- 列子
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]];
BOOL res5 = [(id)[Sark class] isKindOfClass:[NSObject class]];
BOOL res6 = [(id)[Sark class] isMemberOfClass:[NSObject class]];
打印結(jié)果:
2019-09-20 15:10:22.235225+0800 sortTime[2852:215634] 1 0 0 0 1 0
- 驗(yàn)證 [(id)[NSObject class] isKindOfClass:[NSObject class]]返回YES
詳解- isKindOfClass內(nèi)部實(shí)現(xiàn)
//逆向反編譯得到的源碼
- (BOOL) isKindOfClassITX:(Class)class
{
NSLog(@"class->%@:%p",NSStringFromClass(class), class);
NSLog(@"%p",[NSObject class]);
Class r0 = object_getClass(self);
while (1) {
if (r0 == 0) {
return 0;
}else{
NSLog(@"r0->%@:%p",NSStringFromClass(r0), r0);
if (r0 != class) {
r0 = [r0 superclass];
}else{
return 1;
}
}
}
}
- 驗(yàn)證結(jié)果
BOOL res7 = [(id)[NSObject class] isKindOfClassITX:[NSObject class]];
NSLog(@"%d",res7);
2019-09-20 15:28:49.632315+0800 sortTime[3104:232025] class->NSObject:0x10ec42ec8
2019-09-20 15:28:49.632647+0800 sortTime[3104:232025] 0x10ec42ec8
2019-09-20 15:29:34.024142+0800 sortTime[3104:232025] r0->NSObject:0x10ec42e78
2019-09-20 15:29:40.357044+0800 sortTime[3104:232025] r0->NSObject:0x10ec42ec8
-
總結(jié):
(1)透绩、1號(hào)[NSObject class](類對(duì)象)
對(duì)應(yīng)的元類(根元類)
對(duì)象和2號(hào)[NSObject class](類對(duì)象翘骂,也是根類對(duì)象)
比較是否相等,如果不等.
(2)帚豪、1號(hào)對(duì)象元類superClass指針指向的父類(此時(shí)的父類是根類對(duì)象)和2號(hào)[NSObject class](類對(duì)象碳竟,也是根類對(duì)象)
比較是否相等,此時(shí)相等狸臣。
-
驗(yàn)證 [(id)[Sark class] isKindOfClass:[NSObject class]]返回YES
- 驗(yàn)證結(jié)果
BOOL res7 = [(id)[Person class] isKindOfClassITX:[NSObject class]];
NSLog(@"%d",res7);
2019-09-20 16:11:43.234421+0800 sortTime[3541:269003] class->NSObject:0x101a32ec8
2019-09-20 16:11:43.234500+0800 sortTime[3541:269003] 0x101a32ec8
2019-09-20 16:11:43.234565+0800 sortTime[3541:269003] 0x1009df9a8
2019-09-20 16:11:48.343621+0800 sortTime[3541:269003] r0->Person:0x1009df980
2019-09-20 16:11:48.343945+0800 sortTime[3541:269003] r0->NSObject:0x101a32e78
2019-09-20 16:11:48.344146+0800 sortTime[3541:269003] r0->NSObject:0x101a32ec8
-
總結(jié):
(1)莹桅、1號(hào)[Person class](類對(duì)象)
對(duì)應(yīng)的元類3號(hào)(元類)
對(duì)象和2號(hào)[NSObject class](根類對(duì)象)
比較是否相等,此時(shí)不等.
(2)烛亦、3號(hào)對(duì)象superClass指針指向的父類4號(hào)對(duì)象(此時(shí)的父類是根元類對(duì)象
)和2號(hào)[NSObject class](根類對(duì)象)
比較是否相等诈泼,此時(shí)不等。
(3)此洲、4號(hào)對(duì)象(根元類)
superClass指向的父類5號(hào)對(duì)象(根類對(duì)象)
和2號(hào)[NSObject class](根類對(duì)象)
比較是否相等厂汗,此時(shí)相等。
-
驗(yàn)證 [[Person new] isKindOfClassITX:[NSObject class]]返回YES
- 驗(yàn)證結(jié)果
BOOL res7 = [[Person new] isKindOfClassITX:[NSObject class]];
NSLog(@"%d",res7);
2019-09-20 16:41:06.241951+0800 sortTime[3781:288460] class->NSObject:0x10f2c0ec8
2019-09-20 16:41:06.242027+0800 sortTime[3781:288460] 0x10f2c0ec8
2019-09-20 16:41:06.242092+0800 sortTime[3781:288460] 0x60000326c520
2019-09-20 16:41:11.159426+0800 sortTime[3781:288460] r0->Person:0x10e26d9a8
2019-09-20 16:41:11.159572+0800 sortTime[3781:288460] r0->NSObject:0x10f2c0ec8
-
總結(jié):
(1)呜师、1號(hào)[Person new](實(shí)例)
對(duì)應(yīng)的元類3號(hào)(類對(duì)象)
對(duì)象和2號(hào)[NSObject class](根類對(duì)象)
比較是否相等娶桦,此時(shí)不等.
(2)、3號(hào)對(duì)象superClass指針指向的父類4號(hào)對(duì)象(此時(shí)的父類是根類對(duì)象
)和2號(hào)[NSObject class](根類對(duì)象)
比較是否相等,此時(shí)相等等衷畦。
isMemberOfClass
isMemberOfClass的源碼實(shí)現(xiàn)是拿到自己的isa指針和自己比較栗涂,是否相等。