Cocoa 深入淺出Cocoa 之動態建立類

2021-06-23 06:50:17 字數 3399 閱讀 4803

在前文

《深入淺出cocoa之類與物件》

一文中,我已經詳細介紹了objc中的 class 與 object 的概念,今天我們來如何在執行

時動態建立類。下面這個函式就是應用前面講到的class,metaclass的概念,在執行時動態建立乙個類。這個函式來自《inside mac os x-the objective-c programming language》。

#import 

#import 

bool createclassdefinition( 

const

char * name, 

const

char * superclassname)

//確保要建立的類不存在

if (objc_lookupclass (name) != nil)

//查詢 root class,因為 meta class 的 isa 指向 root class 的 meta class

root_class = super_class;

while( root_class->super_class != nil )

//為 class 及其 meta class 分配記憶體

new_class = calloc( 2, 

sizeof(

struct objc_class) );

meta_class = &new_class[1]; //

設定 class

new_class->isa = meta_class;

new_class->info = cls_class;

meta_class->info = cls_meta; //

拷貝類名字,這裡為了提高效率,讓 class 與 meta class 都指向同乙個類名字串

new_class->name = malloc (strlen (name) + 1);

strcpy ((

char*)new_class->name, name);

meta_class->name = new_class->name; //

分配並置空 method lists,我們可以在之後使用 

class_addmethods 向類中增加方法

new_class->methodlists = calloc( 1, 

sizeof(

struct objc_method_list *) );

meta_class->methodlists = calloc( 1, 

sizeof(

struct objc_method_list *) ); //

將類加入到繼承體系中去:

//1,設定類的 super class

//2,設定 meta class 的 super class

//3,設定 meta class 的 isa

new_class->super_class = super_class;

meta_class->super_class = super_class->isa;

meta_class->isa = (

void *)root_class->isa; //

最後,將 class 註冊到執行時系統中

objc_addclass( new_class );

return yes; }

如果要在**中使用執行時相關的函式,我們需要匯入 libobjc.dylib,並匯入相關的標頭檔案(比如這裡的 runtime.h)。在前文

中總結到「

objc 為每個類的定義生成兩個 objc_class ,乙個即普通的 class,另乙個即 metaclass。我們可以在執行期建立這兩個 objc_class 資料結構,然後使用 objc_addclass 動態地建立新的類定義。

」,這在上面的**中就體現出來了:new_class 和 meta_class 就是新類所必須的兩個 objc_class。其他的**就不解釋了,注釋以及**足以自明了。

在實際的運用中,我們使用 objc 執行時函式來動態建立類:

class objc_allocateclasspair(class superclass, 

const

char *name, size_t extrabytes);

譬如:#import 

#import 

void reportfunction(id self, sel _cmd)

nslog(@" >> nsobject's class is %p", [nsobject 

class]);

nslog(@" >> nsobject's meta class is %p", object_getclass([nsobject 

class])); }

int main (

int argc, 

const

char * argv)

return 0; }

在上面的**中,我們建立繼承自 nsstring 的子類 

nsstringsubclass

,然後向其中新增方法 report,並在執行時系統中註冊,這樣我們就可以使用這個新類了。在這裡使用 performselector 來向新類的物件傳送訊息,可以避免編譯警告資訊(因為我們並沒有宣告該類及其可響應的訊息)。

執行結果為:

>> this 

object

is 0x100114710.

>> class 

is nsstringsubclass, and super 

is nsstring.

>> following the isa pointer 1 times gives 0x100114410

>> following the isa pointer 2 times gives 0x100114560

>> following the isa pointer 3 times gives 0x7fff7e257b50

>> nsobject's class is 0x7fff7e257b78

>> nsobject's meta class is 0x7fff7e257b50

根據前文中的類關係圖,我們不難從執行結果中分析出 nsstringsubclass 的內部類結構:

1,物件的位址為 :

0x100114710

2,class 的位址為:

0x100114410

3,meta class 的位址為:

0x100114560

4,meta class 的 class 位址為:

0x7fff7e257b50

(也是 nsobject 的 meta class)

5,nsobject 的 meta class 的 meta class 是其自身

Cocoa 深入淺出Cocoa系列

深入淺出cocoa系列 羅朝輝 本文遵循 署名 非商業用途 保持一致 創作公用協議 這是本人在研究 cocoa 開發過程中寫過的一些文章,涵蓋 runtime,class,message,多執行緒,core data,網路,framework,plugin等各方面,還比較成系列,所以整理出來,貼在這...

Cocoa 深入淺出Cocoa 之動態建立類

深入淺出cocoa 之動態建立類 羅朝輝 本文遵循 署名 非商業用途 保持一致 創作公用協議 在前文 深入淺出cocoa之類與物件 一文中,我已經詳細介紹了objc中的 class 與 object 的概念,今天我們來如何在執行 時動態建立類。下面這個函式就是應用前面講到的class,metacla...

深入淺出Cocoa之類與物件

本文 最近打算寫一些objc中比較底層的東西,尤其是 runtime 相關的。蘋果已經將 objc runtime 開源了,我們可以從 瀏覽源 或 源 從 入手呢?那當然是最基本的類與物件。與c 相比,objc中的類與物件結構要簡潔與一致得多 參考 深度探索c 物件模型 你就知道c 中類與物件結構的...