概述
? ? ?OC正是由于有了runtime才使得c語言具有了面向對象的能力,在程序的運行時刻,創(chuàng)建,檢查,修改類、對象以及類、對象的方法。
? ? 為什么會這么說?OC中的對象、類又到底是一個什么樣的數據結構,對象、類又是如何用C來描述的呢?帶著這樣的問題,我們首先來看一下在OC中類的定義。
Class
? ? 在objc/runtime.h中objc_class結構體的定義如下:
struct objc_class {
Class isaOBJC_ISA_AVAILABILITY;//isa指針指向Meta Class,因為objc類本身也是一個object(對象),為了處理這個關系,runtime創(chuàng)造了Meta Class,當一個類發(fā)送[NSObject alloc]這樣消息時,實際上是把消息發(fā)送給Class object類對象
#if !__OBJC2__
Class super_classOBJC2_UNAVAILABLE;//父類
const char *nameOBJC2_UNAVAILABLE;//類名
long versionOBJC2_UNAVAILABLE;//類的版本信息,默認為0
long infoOBJC2_UNAVAILABLE;//類信息,供運行時使用的一些位表示
long instance_sizeOBJC2_UNAVAILABLE;//該類的實例變量大小
struct objc_ivar_list *ivarsOBJC2_UNAVAILABLE;//該類的成員變量的鏈表
struct objc_method_list **methodListsOBJC2_UNAVAILABLE;//方法定義的鏈表
struct objc_cache *cacheOBJC2_UNAVAILABLE;//方法緩存,對象接到一個消息會根據isa指針查找消息對象,這時會在methodLists中遍歷,如果cache了,常用的方法調用時就能夠提高調用的效率。
struct objc_protocol_list *protocolsOBJC2_UNAVAILABLE;//協(xié)議鏈表
#endif
} OBJC2_UNAVAILABLE;
在objc.h中有這樣一個定義
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
即:OC當中任何一個類都是用objc_class這樣一個結構體來描述的。
objc_object與id
? ? objc_object是一個類的實例結構體,objc/objc.h中objc_object是一個類的實例結構體定義如下:
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
typedef struct objc_object *id;
? ? 與objc_class相同,在OC當中用一個結構體描述一個對象;在向object發(fā)送消息的時候,runtime會根據object的isa指針找到這個實例的object所屬于的類,然后在類的方法列表以及父類的方法列表中尋找對應的方法運行。
? ? id是一個objc_object結構類型的指針,這個類型的對象能夠轉換任何一種對象。
Meta Class
? ? 大家可能注意到,一個對象的isa指針會指向它的類。然而在面向對象的世界里,一切都是對象,即:一個類也是一個對象,那么問題來了,那這個類對象它的類是誰呢(可能有點繞大家稍微理解一下這覺話)?類對象的isa指針又會指向哪里呢?
? ?為了解決這個問題,runtime創(chuàng)造了元類(Meta Class)。即一個類的是它元類的實例話,一個類的isa指針是指向它的元類。和對象一樣,我們向一個類發(fā)送消息的時候,isa指針會在元類中以及元類的父類方法列表尋找對應的方法運行。
? ? 既然一切都是對象那么元類也是對象,那么元類的類是誰?元類的isa指針指向哪里呢?下面這張經典的圖完美了解釋了一些,廢話少說上圖:
? ? 即任何一個元類都是根元類的對象,任何一個元類的isa指針都指向了根元類;而根元類的isa指針又指向了它自己;形成了一個閉環(huán),這樣就完美的詮釋了面向對象的世界里萬物皆對象的概念。(這張圖,大家一定要好好的理解一下,如果今天看不懂,那么我給的建議是明天再看一遍,如果明天還看不懂,那就后天,如果還是不懂,那就過段時間再來看,如此反復,直到成功)
? ? 好吧,到這里大家應該明白了,oc其實就是在用c的結構體來描述類和對象,通過一個isa指針指來指去完成了方法的調用,對于c系的同學來說應該不會有太大的難度。。。
后面會繼續(xù)寫關于runtime的知識。今天就先到這里吧,打卡,下班,回家。。。
順道拜托,若文中有任何理解不正確的地方歡迎指出