源碼下載地址:https://opensource.apple.com/tarballs/objc4/,我下載了當前最新的objc4-779.1.tar.gz
注:iPhone 程序和 Mac OS X v10.5 及以后的系統(tǒng)中的 64 位程序使用的都是 Objective-C 運行時系統(tǒng)的objc 2.0版本审残。源碼中有大量宏條件, 注意查看條件。如
#if !__OBJC2__
, 此條件下的代碼是無效的驮配,網(wǎng)上流傳的許多以前的資料是過時的每窖,有助于理解酝蜒,但注意區(qū)分。
對象
OC是一門面向?qū)ο蟮恼Z言向胡,一切皆對象恼蓬。OC中定義的對象是struct objc_object
,被定義在了objc-private.h
文件中僵芹。
struct objc_object {
private:
isa_t isa;
public:
Class ISA();
Class rawISA();
Class getIsa();
uintptr_t isaBits() const;
void initIsa(Class cls /*nonpointer=false*/);
void initClassIsa(Class cls /*nonpointer=maybe*/);
void initProtocolIsa(Class cls /*nonpointer=maybe*/);
void initInstanceIsa(Class cls, bool hasCxxDtor);
Class changeIsa(Class newCls);
....
}
這里面有一個最重要的私有變量isa
,它是一個指針处硬,指向的是什么,用一個清晰明了的圖來看一下(superclass
看下段中類的源碼就明白了)拇派。
注:根元類一般是
NSObject
, 還有一個NSProxy
疮方,這里假定Cat
繼承自NSObject
控嗜,如果繼承自NSProxy
,圖中的NSObject
換成NSProxy
即可骡显。
此文件中也能找到id
的定義疆栏,typedef struct objc_object *id;
。那么也就能理解為什么id
能指向任何對象了惫谤。
類
類其實也是一個對象壁顶,被定義為struct objc_class
,在objc-runtime-new.h
文件中溜歪,繼承自objc_object
若专。
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
class_rw_t *data() const {
return bits.data();
}
void setData(class_rw_t *newData) {
bits.setData(newData);
}
void setInfo(uint32_t set) {
ASSERT(isFuture() || isRealized());
data()->setFlags(set);
}
....
}
cache_t cache
cache 是為了方法調(diào)用性能優(yōu)化,將調(diào)用過的方法緩存痹愚,當對某個對象發(fā)送消息時先從cache中找,找不到再到isa指向的類中尋找方法實現(xiàn)蛔糯。提高效率拯腮。
class_data_bits_t
內(nèi)容很少,重點在包裝的bits.data()
.
class_rw_t
是bits.data()
返回的類型蚁飒。class_rw_t
可以動態(tài)修改动壤。可以動態(tài)添加方法淮逻、屬性到methods
,properties
,properties
中琼懊。class_rw_t
包含class_ro_t
。
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint16_t version;
uint16_t witness;
const class_ro_t *ro;
method_array_t methods;
property_array_t properties;
protocol_array_t protocols;
...
class_ro_t
存儲的大多是類在編譯時就已經(jīng)確定的信息爬早。
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name;
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
...
}
元類
類也是對象哼丈,是某個類的實例。這個“某個類”被稱為元類筛严。
- 類的isa指針指向其元類
- 元類也是某個類的實例醉旦,這個“某個類”被稱為根元類。
- 元類的isa指針指向根元類桨啃,根元類的isa指針指向自己
- 類方法保存在元類中
參考:
- 證明isa指向關(guān)系车胡,以及簇類
https://blog.csdn.net/u013480070/article/details/100155929 - 對象的方法存在類中,類方法存在元類中
https://juejin.im/post/5ac649b6518825558a06da89 - 雷純鋒Objective-C 對象模型
- YY大神的 Objective-C 中的類和對象
- 玉令天下Objective-C Runtime