標籤:
本系列主要參考資料:
Objective-C Runtime Reference
Objective-C Runtime Programming Guide
涉及主要檔案:objc/message.h,objc/objc-api.h,objc/objc.h,objc/runtime.h
特酷吧[tekuba.net]採用"署名-非商業用途-保持一致"的創作共用協議,使用本文內容請遵循該協議
Objective-C Runtime是Objective-C的基礎內容,理解了Objective-C Runtime對於掌握Objective-C的很多技術原理非常有用。特酷吧特別整理了Objective-C Runtime的內容,共六篇,本文是第二篇:
《Objective-C Runtime分析(一)-Runtime初步》
《Objective-C Runtime分析(二)-Class,Method,SEL,IMP》
《Objective-C Runtime分析(三)-objc_msgSend》
《Objective-C Runtime分析(四)--Dynamic Method Resolution》
《Objective-C Runtime分析(五)-Message Forwarding》
《Objective-C Runtime分析(六)-Type Encodings & Declared Properties》
本文參考地址:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtHowMessagingWorks.html
本文主要分析了與Objective-C Runtime密切相關的幾個資料類型/概念:Class , Method,,SEL , IMP ,他們都在objc/objc.h中定義。先來看看他們的定義。
摺疊展開C/C++ Code複製內容到剪貼簿
- typedef struct objc_class *Class;
- typedef struct objc_object {
- Class isa;
- } *id;//可以看到,iOS中很重要的id實際上就是objc_object的指標.而NSObject的第一個對象就是Class類型的isa。因此id可以標示所有基於NSObject的對象。
- typedef struct objc_selector *SEL;
- #if !OBJC_OLD_DISPATCH_PROTOTYPES
- typedef void (*IMP)(void /* id, SEL, ... */ );
- #else
- typedef id (*IMP)(id, SEL, ...);
- #endif
一,Class
Class 被定義為一個指向objc_class的結構體指標,表示一個類的類結構。objc_class在objc/objc_class.h中定義如下:
摺疊展開C/C++ Code複製內容到剪貼簿
- struct objc_class {
- Class isa;
-
- #if !__OBJC2__
- Class super_class OBJC2_UNAVAILABLE;/*父類*/
- const char *name OBJC2_UNAVAILABLE;/*類名稱*/
- long version OBJC2_UNAVAILABLE;/*版本資訊*/
- long info OBJC2_UNAVAILABLE;/*類資訊*/
- long instance_size OBJC2_UNAVAILABLE;/*執行個體大小*/
- struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;/*執行個體參數鏈表*/
- struct objc_method_list **methodLists OBJC2_UNAVAILABLE;/*類方法鏈表*/
- struct objc_cache *cache OBJC2_UNAVAILABLE;/*類方法緩衝*/
- struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;/*協議鏈表*/
- #endif
- } OBJC2_UNAVAILABLE;
可見,Class是指向類結構體的指標,該類結構體含有一個指向其父類類結構的指標,該類方法的鏈表,該類方法的緩衝以及其他資訊。
NSObject 的class方法就返回這樣一個指向其類結構的指標。每一個基於NSObject的類執行個體對象都有一個指向該對象的類結構的指標,叫做isa。通過該指標,對象可以訪問它對應的類以及相應的父類。
二,Method
Method是Runtime內部定義的方法,Class中定義有一個objc_method_list,鏈表都是objc_method類型的,定義如下:
摺疊展開C/C++ Code複製內容到剪貼簿
- typedef struct objc_method *Method;
- struct objc_method {
- SEL method_name OBJC2_UNAVAILABLE;/*標示方法名稱*/
- char *method_types OBJC2_UNAVAILABLE;/*方法的參數類型*/
- IMP method_imp OBJC2_UNAVAILABLE;/*指向該方法的具體實現的函數指標*/
- }
-
- struct objc_method_list {
- struct objc_method_list *obsolete OBJC2_UNAVAILABLE;
-
- int method_count OBJC2_UNAVAILABLE;
- #ifdef __LP64__
- int space OBJC2_UNAVAILABLE;
- #endif
- /* variable length structure */
- struct objc_method method_list[1] OBJC2_UNAVAILABLE;
- }
三,SEL
定義如下:
typedef struct objc_selector *SEL;
標示該方法的名字/簽名
樣本:
-(void)helloTekuba:(NSString *)url port:(int)port
{
NSLog(@"%@,%d",url,port);
}
NSLog(@"SEL = %s",@selector(helloTekuba:port:));
列印結果:
SEL = helloTekuba:port:
不同的類可以擁有相同的selector,不同類的執行個體對象performSelector相同的selector時,會在各自的方法鏈表中根據 selector 去尋找具體的方法實現IMP, 然後用這個方法實現去執行具體的實現代碼。這是一個動態綁定的過程,在編譯的時候,我們不知道最終會執行哪一些代碼,只有在執行的時候,通過selector去查詢,我們才能確定具體的執行代碼。
四,IMP
typedef id (*IMP)(id, SEL, ...);
我們知道 id是一個指向 objc_object 結構體的指標(請看本文前面objc_object的定義),該結構體只有一個成員isa,所以任何繼承自 NSObject 的類對象都可以用id 來指代,因為 NSObject 的第一個成員執行個體就是isa。
IMP 是一個函數指標,這個被指向的函數包含一個接收訊息的對象id, 調用方法的選標 SEL,以及不定個數的方法參數,並返回一個id。也就是說IMP是訊息最終調用的執行代碼,是方法真正的實現代碼 。我們可以像在C語言裡面一樣使用這個函數指標。
NSObject 類中的methodForSelector:方法就是這樣一個擷取指向方法實現IMP 的指標,methodForSelector:返回的指標和賦值的變數類型必須完全一致,包括方法參數類型和傳回值類型。
五,其他
Ivar
Runtime中用來表示instance variable,執行個體變數,跟某個對象關聯,不能被靜態方法使用,與之想對應的是class variable,其聲明如下:
typedef struct objc_ivar *Ivar;
Category
Runtime中用來表示Category,其聲明為:
typedef struct objc_category *Category;
Catagory可以動態地為已經存在的類添加新的行為。這樣可以保證類的原始設計規模較小,功能增加時再逐步擴充。使用Category對類進行擴充時,不需要訪問其原始碼,也不需要建立子類。關於更多Catagory的知識可以參考:http://www.tekuba.net/program/312/
轉載請註明來自特酷吧,本文地址:www.tekuba.net/program/336/
推薦閱讀:
XCode lipo命令使用的一點知識
UINavigationController彈出(pop)和壓入(push)操作的一個問題
IOS後台運行淺析
IOS7 Background Fetch後台應用程式重新整理
IOS NSProcessInfo擷取系統開機累計時間
想及時擷取特酷吧的更新?想瞭解iOS,android開發最新技術動態,點擊或掃描下方二維碼下載“多識閱讀”App,豐富的iOS,Android,Web等領域開發人員部落格隨你訂閱。
《Objective-C Runtime分析(二)-Class,Method,SEL,IMP》