深入淺出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, constchar *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 objectis0x100114710.
>> 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 中類與物件結構的...