一建峭、OC對象的分類
OC對象主要可以分為三種:
instance對象(實(shí)例對象)
class對象(類對象)
meta-class對象(元類對象)
1.instance對象就是通過類alloc出來的對象症副,每次調(diào)用alloc都會產(chǎn)生新的instance對象凌受。object1和object2都是NSObject的instace對象(實(shí)例對象)阵子,但他們是不同的兩個對象,并且分別占據(jù)著兩塊不同的內(nèi)存胜蛉。
NSObjcet *object1 = [[NSObjcet alloc] init];
NSObjcet *object2 = [[NSObjcet alloc] init];
instance對象在內(nèi)存中存儲的信息包括:1.isa指針 2.其他成員變量挠进。
那么一個NSObject對象占用多少內(nèi)存?
NSObjcet實(shí)際上是只有一個名為isa的指針的結(jié)構(gòu)體誊册,因此占用一個指針變量所占用的內(nèi)存空間大小领突,如果64bit占用8個字節(jié),如果32bit占用4個字節(jié)案怯。
2.每一個類在內(nèi)存中有且只有一個class對象君旦。可以通過打印內(nèi)存地址證明
Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = [NSObject class];
// runtime
Class objectClass4 = object_getClass(object1);
Class objectClass5 = object_getClass(object2);
NSLog(@"%p %p %p %p %p", objectClass1, objectClass2, objectClass3, objectClass4, objectClass5);
class對象在內(nèi)存中存儲的信息主要包括:
isa指針
superclass指針
類的屬性信息(@property),類的成員變量信息(ivar)
類的對象方法信息(instance method)金砍,類的協(xié)議信息(protocol)
成員變量的值時存儲在實(shí)例對象中的局蚀,因?yàn)橹挥挟?dāng)我們創(chuàng)建實(shí)例對象的時候才為成員變賦值。但是成員變量叫什么名字恕稠,是什么類型琅绅,只需要有一份就可以了。所以存儲在class對象中鹅巍。
3.元類對象 meta-class
//runtime中傳入類對象此時得到的就是元類對象
Class objectMetaClass = object_getClass([NSObject class]);
// 而調(diào)用類對象的class方法時得到還是類對象千扶,無論調(diào)用多少次都是類對象
Class cls = [[NSObject class] class];
Class objectClass3 = [NSObject class];
class_isMetaClass(objectMetaClass) // 判斷該對象是否為元類對象
NSLog(@"%p %p %p", objectMetaClass, objectClass3, cls); // 后面兩個地址相同,
說明多次調(diào)用class得到的還是類對象
每個類在內(nèi)存中有且只有一個meta-class對象骆捧。
meta-class對象和class對象的內(nèi)存結(jié)構(gòu)是一樣的县貌,但是用途不一樣,在內(nèi)存中存儲的信息主要包括:
isa指針
superclass指針
類的類方法的信息(class method)
meta-class對象和class對象的內(nèi)存結(jié)構(gòu)是一樣的凑懂,所以meta-class中也有類的屬性信息煤痕,類的對象方法信息等成員變量,但是其中的值可能是空的接谨。
二摆碉、對象的isa指針指向哪里
1.instance的isa指向class,當(dāng)調(diào)用對象方法時脓豪,通過instance的isa找到class巷帝,最后找到對象方法的實(shí)現(xiàn)進(jìn)行調(diào)用。
2.class的isa指向meta-class
當(dāng)調(diào)用類方法時扫夜,通過class的isa找到meta-class楞泼,最后找到類方法的實(shí)現(xiàn)進(jìn)行調(diào)用
3.當(dāng)對象調(diào)用其父類對象方法的時候,又是怎么找到父類對象方法的呢笤闯?堕阔,此時就需要使用到class類對象superclass指針。
當(dāng)Student的instance對象要調(diào)用Person的對象方法時颗味,會先通過isa找到Student的class超陆,然后通過superclass找到Person的class,最后找到對象方法的實(shí)現(xiàn)進(jìn)行調(diào)用浦马,同樣如果Person發(fā)現(xiàn)自己沒有響應(yīng)的對象方法时呀,又會通過Person的superclass指針找到NSObject的class對象,去尋找響應(yīng)的方法
4.當(dāng)類對象調(diào)用父類的類方法時晶默,就需要先通過isa指針找到meta-class谨娜,然后通過superclass去尋找響應(yīng)的方法。
當(dāng)Student的class要調(diào)用Person的類方法時磺陡,會先通過isa找到Student的meta-class趴梢,然后通過superclass找到Person的meta-class漠畜,最后找到類方法的實(shí)現(xiàn)進(jìn)行調(diào)用。
最后又是這張靜定的isa指向圖垢油,經(jīng)過上面的分析我們在來看這張圖盆驹,就顯得清晰明了很多。
對isa滩愁、superclass總結(jié)
1.instance的isa指向class
2.class的isa指向meta-class
3.meta-class的isa指向基類的meta-class躯喇,基類的isa指向自己
4.class的superclass指向父類的class,如果沒有父類硝枉,superclass指針為nil
5.meta-class的superclass指向父類的meta-class廉丽,基類的meta-class的superclass指向基類的class
6.instance調(diào)用對象方法的軌跡,isa找到class妻味,方法不存在正压,就通過superclass找父類
7.class調(diào)用類方法的軌跡,isa找meta-class责球,方法不存在焦履,就通過superclass找父類
本文面試題總結(jié):
一個NSObject對象占用多少內(nèi)存?
答:一個指針變量所占用的大谐狻(64bit占8個字節(jié)嘉裤,32bit占4個字節(jié))
對象的isa指針指向哪里?
答:instance對象的isa指針指向class對象栖博,class對象的isa指針指向meta-class對象屑宠,meta-class對象的isa指針指向基類的meta-class對象,基類自己的isa指針也指向自己仇让。
OC的類信息存放在哪里典奉?
答:成員變量的具體值存放在instance對象。對象方法丧叽,協(xié)議卫玖,屬性,成員變量信息存放在class對象蠢正。類方法信息存放在meta-class對象骇笔。