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

2021-09-08 15:57:58 字數 3402 閱讀 5623

深入淺出cocoa 之動態建立類

羅朝輝 (

本文遵循「署名-非商業用途-保持一致」創作公用協議

在前文《深入淺出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 * ar**)

return

0;}

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

nsstringsubclass

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

執行結果為:

>> this object

is0x100114710.

>> 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之類與物件 一文中,我已經詳細介紹了objc中的 class 與 object 的概念,今天我們來如何在執行 時動態建立類。下面這個函式就是應用前面講到的class,metaclass的概念,在執行時動態建立乙個類。這個函式來自 inside mac os x the ob...

深入淺出Cocoa之類與物件

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