runtime是一個頗有意思的東西,若是你學iOS開發很常常就會用到或被問到runtime。那麼runtime是什麼呢,如何去了解它。ios
runtime:中文名 運行時,系統在編譯時留下的一些 類型,操做在運行的時候動態去分析,處理,這也說明了object-c是一個動態語言。(swift與之不一樣,swift雖然能夠經過調用oc的runtime,可是swift自己是靜態語言。可是卻經過可以和oc交互變成了具備動態特性的靜態語言,這是閒話,不扯了)。c++
要了解runtime,知道runtime是什麼。我以爲最關鍵的是看 objc/objc.h,objc/runtime.h文件。swift
首先要知道object-c底層是用c,c++寫的數組
A. objc.h:緩存
一、objc.h文件裏面定義了一個id 是一個objc_object結構體指針類型,結構體中又一個isa這樣的成員,isa是一個Class類型。而Class是 objc_class * 類型app
也就是說一個 oc中的object其實就是一個帶有objc_class*成員,並由這個objc_class*類型的成員來解釋這個object是什麼東西,包括這個object是什麼類型,有什麼方法。方法參數組成,有什麼協議,類別等。學習
typedef struct objc_class *Class;spa
struct objc_object {指針
Class isa OBJC_ISA_AVAILABILITY;對象
};
二、而後咱們來看 Class這個類型,Class這個類型是objc_class*的別名。具體意思不就是說是用objc_class這個結構體對應的指針類型。
三、接着是SEL, 跟Class差很少這個也是另一個結構體指針的別名,這個對應的結構體叫作objc_selector.
其中objc_object能夠在runtime中看到具體的結構。objc_selector我沒找到在哪裏,誰看到了提醒一下哦。
四、而後是方法實現的定義:
/// A pointer to the function of a method implementation.
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif
接着下面是定義了一些對方法名,變量的一些操做。
B.runtime.h
runtime.h文件中定義了不少的結構體和方法。
一、首先是給幾個結構體指針類型定義了幾個別名 objc_method * 對應Method, objc_ivar *對應Ivar,objc_catagory *對應 Catagory objc_property *對應objc_property_t 類型。
二、objc_class 結構體
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#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;
從上面這個結構中能夠看到一個objc_class中有一個 Class 定義的isa成員,這個成員其實在A中能夠看出來 其實也是一個objc_class *這種類型。(這種定義方式在咱們學習c++的時候有學過。譚浩強的《面向對象c++》..)
而後咱們這時要知道object-c裏面的類和實例其實都是一個定義的對象,並且對應的指針是isa .也就是說系統 像malloc這個操做後會把 指針存到這個 isa中。
這樣其實object-c裏面的類和對象其實都是經過結構體指針來實現的。
而後咱們再看 objc_class中的結構其中包括了 父類,類名,版本, 示例大小,實例中包含的變量列表,方法列表,緩存,協議列表。這些東西
在往下看 能夠看到Protocol是一個objc_object類型,而後經過objc_object裏面的isa 指針保存對應的名字,方法,變量等。因此經過這個你能夠認識到定義一個協議是能夠往裏面加你要的屬性的。
而後往下
objc_method_description的結構體這個東西定義了方法有方法名和方法類型
objc_property_attribute_t這個結構體定義了屬性的特色包括須要有 名稱 和 值。
再往下看有不少對實例在運行時的操做,這裏我就省略了。又一個方法叫
imp_implementationWithBlock
從這裏能夠拿到一個block的對應的實現的指針。(block是一個對象)
再往下有給object設置關聯的方法,這些操做就是平時用到的在類別中如何給一個類添加一些屬性(類別中是不能添加屬性的,不過經過這個方法能夠爲你定義的屬性的set,和get方法至關於重寫的操做。而後實現了一個類別的屬性)
objc_setAssociatedObject
objc_getAssociatedObject
objc_removeAssociatedObjects
再往下走又是一堆結構體 protocol_list, objc_catagory, objc_ivar, objc_ivar_list, objc_method, objc_method_list, objc_cache, objc_module.
這些結構體分別對應的定義了咱們在oc中常常用到的 類別,方法等東西的結構(含糊的講一下,有點多)
總結一下,也就是說其實ios的runtime是經過不少個 struct類型來緩存對應的結構並在運行的時候經過這些結構特徵和對應的指針來分析並進行對應的操做。
因此多看裏面的結構組成就對了。
以上屬於我的理解
推薦一篇講的蠻詳細的(http://chun.tips/blog/2014/11/06/bao-gen-wen-di-objective[nil]c-runtime(3)[nil]-xiao-xi-he-category/)
若是想更深刻了解具體內部實現原理,就要看opensource.apple.com裏面的內容了,如: https://opensource.apple.com//source/objc4/objc4-706/runtime/