一、什麼是Objective-C runtime?
簡單來說,Objective-C runtime是一個實現Objective-C語言的C庫。對象可以用C語言中的結構體表示,而方法(methods)可以用C函數實現。事實上,他們 差不多也是這麼干了,另外再加上了一些額外的特性。這些結構體和函數被runtime函數封裝後,Objective-C程序員可以在程序運行時創建,檢 查,修改類,對象和它們的方法。
除了封裝,Objective-C runtime庫也負責找出方法的最終執行代碼。當程序執行[object doSomething]時,不會直接找到方法並調用。相反,一條消息(message)會發送給對象(在這兒,我們通常叫它接收者)。runtime庫 給次機會讓對象根據消息決定該作出什麼樣的反應。Alan Kay反復強調消息傳遞(message-passing)是Smalltalk最重要的部分(Objective-C根據Smalltalk發展而來),而不是對象。
Objective-C是一個面向運行時的語言。所以問題就是,什麼是一個運行時語言?一個運行時語言就是在應用程序運行的時候來決定函數內部實現什麼以及做出其它決定的語言。Objective-C是一個運行時語言嗎?不是。它是一個面向運行時的語言,這意味著只要有可能,它就把做決定的時間從編譯時和鏈接時延遲到這段代碼真正執行的時候。正如前面指出的,Cocoa提供了iOS應用程序所需要的運行時環境
二、runtime中的消息
①message(消息)
message的具體定義很難說,因為並沒有真正的代碼描述,簡單的講message 是一種抽象,包括了函數名+參數列表,他並沒有實際的實體存在。
②method(方法)
method是真正的存在的代碼。如:- (int)meaning { return 42; }
③selector(方法選擇器)
selector 通過SEL類型存在,描述一個特定的method 或者說 message。在實際編程中,可以通過selector進行檢索方法等操作。
三、_cmd關鍵字
- (void)message
{
self.name = @"James";//通過self關鍵字給當前對象的屬性賦值
SEL currentSel = _cmd;//通過_cmd關鍵字取到當前函數對應的SEL
NSLog(@"currentSel is :%s",(char *)currentSel);
}
打印結果:
ObjcRunTime[693:403] currentSel is :message
四、Class 的定義
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
我們可以看到這裡這裡有兩個結構體,一個類結構體一個對象結構體。所有的 objc_object 對象結構體都有一個 isa 指針,這個 isa 指向它所屬的類,在運行時就靠這個指針來檢測這個對象是否可以響應一個 selector。完了我們看到最後有一個 id 指針。這個指針其實就只是用來代表一個 ObjC 對象,有點類似於 C++ 的泛型。當你拿到一個 id 指針之後,就可以獲取這個對象的類,並且可以檢測其是否響應一個 selector。這就是對一個 delegate 常用的調用方式。
五、IMP(Method Implementations)
typedef id (*IMP)(id self,SEL _cmd,...);
一個 IMP 就是一個函數指針,這是由編譯器生成的,當你發起一個 ObjC 消息之後,最終它會執行的那個代碼,就是由這個函數指針指定的。
參考鏈接:
1、理解 Objective-C Runtime
2、iOS開發之深入探討runtime機制01-類與對象
3、Objective-C runtime之運行時的基本特點(一)
4、Objective-C runtime之消息(二)
5、iOS開發:詳解Objective-C runtime
6、Objective-C 的 Runtime 與 Java 的 Runtime 有何差異?