runtime中函數調用經常被提及的三個概念 isa,IMP,SEL
一 isa:是類指針,之所以說isa
是指針是因為Class
其實是一個指向objc_class
結構體的指針,而isa 是它唯一的私有成員變量,即所有對象都有isa指針(isa位置在成員變量第一個位置)
//打開 runtime.h文件可看到下面的類的結構體詳情內容
struct objc_class { Class _Nonnull isa OBJC_ISA_AVAILABILITY;//這個就是上面說的 每個對象都有isa指針 在結構體指針中第一個成員變量的位置上 #if !__OBJC2__ Class _Nullable super_class /*父類*/ const char * _Nonnull name /*類名*/ long version /*版本信息*/ long info /*類信息*/ long instance_size /*實例大小*/ struct objc_ivar_list * _Nullable ivars /*實例參數鏈表*/ struct objc_method_list * _Nullable * _Nullable methodLists /*方法鏈表*/ struct objc_cache * _Nonnull cache /*方法緩存*/ struct objc_protocol_list * _Nullable protocols /*協議鏈表*/ #endif } OBJC2_UNAVAILABLE;
二 IMP:(Implementation縮寫)
(1)它是指向一個方法具體實現的指針,每一個方法都有一個對應的IMP,所以,我們可以直接調用方法的IMP指針,來避免方法調用死循環的問題。
(2)當你發起一個 ObjC 消息之后,最終它會執行的那段代碼,就是由IMP這個函數指針指向了這個方法實現的。
//Method 是一個類實例,里面的結構體有一個方法選標 SEL – 表示該方法的名稱,一個types – 表示該方法參數的類型,一個 IMP - 指向該方法的具體實現的函數指針。
/*
typedef struct objc_method *Method;
typedef struct objc_ method {
SEL method_name; //方法名
char *method_types; //方法類型
IMP method_imp; //具體方法實施的指針
};
*/
Method method = class_getInstanceMethod([self class], NSSelectorFromString(@"dealloc")); //獲取了這個實例方法類Mehtod
IMP classResumeIMP = method_getImplementation(method); //通過實例方法類獲取對應的地址IMP
三 SEL:方法名稱的描述,只記錄方法的編號不記錄具體的方法,具體的方法是 IMP
eg:SEL methodId = @selector(function);
或者
SEL methodId = NSSelectorFromString(@"function")
參考:
1 http://www.cocoachina.com/ios/20150717/12623.html
2 http://blog.csdn.net/dongdongdongjl/article/details/7793156