id類型是什么:
可見id是一個(gè)指向objc_object結(jié)構(gòu)體的指針景馁。
看一條語(yǔ)句就清晰了:
id obj = [[NSObject alloc] init];
所以對(duì)象obj就是一個(gè)objc_object結(jié)構(gòu)體肛根。它們都有個(gè)成員變量isa,其類型為objc_class无畔。它又是一個(gè)指針宅粥,指向objc_class結(jié)構(gòu)體参袱,那么下面再看objc_class里面有什么。
objc_class是什么:
逐條閱讀秽梅,英文不太糟糕的應(yīng)該都沒有障礙:
-
struct objc_class *isa; (最不好理解的)
指向另一個(gè)類的指針抹蚀,這個(gè)“另一個(gè)類”是“元類”(metaclass)。?元類用來(lái)表述類對(duì)象本身所具備的元數(shù)據(jù)企垦】雒“類方法”就定義于此,因?yàn)檫@些方法可以理解成類對(duì)象的實(shí)例方法竹观。每個(gè)類僅有一個(gè)“類對(duì)象”镐捧,而每個(gè)“類對(duì)象”僅有一個(gè)與之相關(guān)的“元類”。(引自《Effective Objective-C 2.0》57頁(yè))(注意臭增,“類對(duì)象”在這句話里是一個(gè)整體懂酱,而不是解釋成類的對(duì)象) -
struct objc_class *super_class;
指向另一個(gè)類的指針,這個(gè)“另一個(gè)類”是超類誊抛,確立繼承關(guān)系列牺。 -
const char *name;
?實(shí)例名 -
long version;
版本 -
long info;
其他信息 -
long instance_size;
實(shí)例大小 -
struct objc_ivar_list *ivars;
實(shí)例變量列表,提供實(shí)例變量信息拗窃,比如類的實(shí)例有多少個(gè)實(shí)例變量瞎领。 -
struct objc_method_list **methodLists;
實(shí)例方法列表泌辫,提供實(shí)例方法信息,比如類的實(shí)例實(shí)現(xiàn)了多少個(gè)方法九默。 - *struct objc_cache cache;
緩存區(qū) -
struct objc_protocol_list *protocols;
實(shí)例實(shí)現(xiàn)的協(xié)議
</br>
具體的例子總是更容易理解的震放,?現(xiàn)在從抽象到具體。
我自定義了一個(gè)類(btw驼修,?許多人寫博都喜歡把自定義的類叫SomeClass殿遂、MyClass、CustomClass等等乙各,這些類名依然會(huì)讓人感覺到很抽象)墨礁,所以我自定義類會(huì)叫Kardel。
Kardel *myKar = [[Kardel alloc] init];
為了更直觀耳峦,我把myK定義成id類型:
id myKar = [[Kardel alloc] init];
如上所言恩静,id是一個(gè)指向objc_object結(jié)構(gòu)體的指針,myK這個(gè)實(shí)例自然就是一個(gè)objc_object結(jié)構(gòu)體了蹲坷。然后蜕企,??根據(jù)我們上面所見,objc_object結(jié)構(gòu)體——即實(shí)例里面只有一個(gè)成員變量冠句,isa指針轻掩。它會(huì)告訴我們這個(gè)實(shí)例所屬的類。
結(jié)論1:類的實(shí)例是objc_object結(jié)構(gòu)體
</br>
結(jié)論2:類是objc_class結(jié)構(gòu)體
</br>
結(jié)論3:objc_class結(jié)構(gòu)體中還有objc_class懦底,即類里面的類——“元類”
</br>
三者之間的繼承關(guān)系:
還有值得思考的問題是為什么要這么做:實(shí)例里面沒有存放很多信息(只有一個(gè)指針唇牧,靠其得知它是什么類),而類負(fù)責(zé)存放實(shí)例的信息聚唐,元類負(fù)責(zé)存放的是類的信息丐重。