什么是runtime
OC是一門(mén)動(dòng)態(tài)語(yǔ)言,它是基于C語(yǔ)言的,它為C 添加了面向?qū)ο蟮奶匦酝⒘!K鼘⒑芏囔o態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了 runtime 運(yùn)行時(shí)來(lái)處理.
runtime運(yùn)用
- 在程序運(yùn)行過(guò)程中,動(dòng)態(tài)的創(chuàng)建類红且,動(dòng)態(tài)添加坝茎、修改這個(gè)類的屬性和方法
- 遍歷一個(gè)類中所有的成員變量、屬性暇番、以及所有方法
- 消息傳遞景东、轉(zhuǎn)發(fā)
在OC中的NSObject對(duì)象定義
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
NSObject只有一個(gè)成員變量isa,它實(shí)際上是一個(gè)指向objc_class結(jié)構(gòu)體的指針
// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;
- 由此可見(jiàn)可以看到Class奔誓、id 都是指針
- id是指向objc_object的一個(gè)指針
- objc_object有個(gè)isa指向objc_class的一個(gè)指針
- id和Class最后指向的都是objc_class這個(gè)結(jié)構(gòu)體
objc_class結(jié)構(gòu)體中的定義如下:
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
類就長(zhǎng)這樣子:
Class 也有一個(gè) isa 指針,指向其所屬的元類
super_class:指向其超類
name:是類名
version:是類的版本信息
info:是類的詳情
instance_size:是該類的實(shí)例對(duì)象的大小
ivars:指向該類的成員變量列表
methodLists:指向該類的實(shí)例方法列表,它將方法選擇器和方法實(shí)現(xiàn)地址聯(lián)系起來(lái)厨喂。methodLists 是指向 objc_method_list 的指針和措,也就是說(shuō)可以動(dòng)態(tài)修改 methodLists 的值來(lái)添加成員方法,這也是 Category 實(shí)現(xiàn)的原理蜕煌,同樣解釋了 Category 不能添加屬性的原因派阱。
cache:Runtime 系統(tǒng)會(huì)把被調(diào)用的方法存到 cache 中以便下次查找的時(shí)候效率更高
protocols:指向該類的協(xié)議列表
在runtime使用當(dāng)中,我們經(jīng)常需要用到的字段斜纪,它們的定義:
- isa 和Class對(duì)象贫母,指向objc_class結(jié)構(gòu)體的指針
- 類的實(shí)例對(duì)象的 isa 指向該類;該類的 isa 指向該類的 MetaClass
- MetaCalss的isa對(duì)象指向RootMetaCalss
- super_class Class對(duì)象指向父類對(duì)象
- 如果該類的對(duì)象已經(jīng)是RootClass,那么這個(gè)super_class指向nil
- MetaCalss的SuperClass指向父類的MetaCalss
-
MetaCalss是RootMetaCalss盒刚,那么該MetaClass的SuperClass指向該對(duì)象的RootClass
OC的方法調(diào)用 Runtime會(huì)轉(zhuǎn)化為消息發(fā)送腺劣,即 objc_msgSend(receiver, selector),即方法的調(diào)用者和方法選擇器因块,當(dāng)做參數(shù)傳遞.
方法的調(diào)用者會(huì)通過(guò) isa 指針來(lái)找到其所屬的類橘原,然后在 cache 或者 methodLists 中查找該方法,找得到就跳到對(duì)應(yīng)的方法去執(zhí)行涡上。
如果在類中沒(méi)有找到該方法趾断,則通過(guò) super_class 往上一級(jí)超類查找
類方法被存儲(chǔ)在元類中,Class 通過(guò) isa 指針即可找到其所屬的元類