什麼是Cocoa中的Meta-class

1.  Objective-C中的對象

Objective-C中,對象的類由isa指針標示,isa指向了對象的類。Objective-C中一個對象的基本定義以下: 函數

typedef struct objc_object {

    Class isa;

} *id;



這就是說,任何起始於指向類的指針的數據類型,都被當作objc_object。因而,Objective-C中的全部類都被當作了對象。 spa

實際上,objc_class定義以下: 指針

typedef struct objc_class *Class; 
struct objc_class {
    Class isa;
    Class super_class;     
    /* followed by runtime specific details... */ 
};



2.  什麼是meta-class

Meta-class與類類似,也是一個對象。類有實例對象,而類可看做是meta-class的實例,即類的isa指向它。它有這麼些特性,結合圖1進行理解。 code

 

l   Meta-class包含了類的類方法; 對象

l   類和meta-class成對出現; 繼承

l   Meta-class也有繼承關係; ci

l   每一個類都有屬於本身的惟一的meta-class class

l   全部的meta-classisa都指向基類的meta-class,基類的meta-class指向自身;基類的meta-class的父類是基類自身,即全部的類和meta-class都繼承自基類(NSObject)。 object

 

 1 實例、類、Meta-class的關係圖 select

3.  爲什麼須要meta-class

爲什麼須要meta-class?這與runtime的消息機制相關。

 

當向對象發送消息時,

3.1.     若對象爲實例對象:[instanceObj foo]

runtime根據isa找到所屬類。該類包含

一個實例方法列表(objc_method_list

一個指向父類的指針,用於查找父類中的實例方法

 

查找過程:

在實例對象所屬的類中的方法列表中查找名爲foo的方法,若沒找到,在其父類中繼續查找,直到找到根類;若找到,則執行foo方法對應的IMP(函數指針)。若繼承關係鏈中的類都沒有,那麼會報錯誤:unrecognized selector sent to instance。其實runtime提供了3種解救方法,能夠動態新增方法或轉發消息。這裏不進行討論。

 

3.2.    對象是類對象:[classObj foo]

runtime根據isa找到所屬meta-class,它包含

一個類方法列表;

一個指向父類的指針,用於查找父類中的類方法

 

查找過程:

          在類對象對應的meta-class的方法列表中查找名爲foo的方法,若沒找到,在其meta-class父類中繼續查找;若找到,則執行foo方法對應的IMP(函數指針)。若繼承關係鏈中的metal-class類都沒有,那麼會報錯誤:unrecognized selector sent to class

相關文章
相關標籤/搜索