什么是runtime?
Objective C語(yǔ)言把能在運(yùn)行期做的事情就推遲到運(yùn)行期再?zèng)Q定。這就意味著,Objective C不僅需要一個(gè)編譯器,而且需要一個(gè)運(yùn)行期環(huán)境。這個(gè)運(yùn)行期環(huán)境就是Runtime。
最直接的例子就是方法調(diào)用
這樣的一個(gè)OC方法
[receiver message]
會(huì)被編譯成
objc_msgSend(receiver, selector)
這里,先記著receiver就是接受消息的對(duì)象,selector是執(zhí)行消息的函數(shù)體名稱,是個(gè)C的字符串。而不是像其他語(yǔ)言一樣,直接編譯成一個(gè)指向函數(shù)體的指針。
那么,在運(yùn)行的時(shí)候,如何通過(guò)objc_msgSend(receiver, selector)找到實(shí)際的函數(shù)體呢?
SEL/objc_selector
objc_selector
透明的數(shù)據(jù)結(jié)構(gòu),可以理解為C StringSEL
源代碼定義
typedef struct objc_selector *SEL;
也就是說(shuō),SEL是指向一個(gè)C String的指針。
id/objc_object
- id
指向一個(gè)類的實(shí)例對(duì)象
底層代碼定義
typedef struct objc_object *id;
其中
- objc_object
底層定義
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
可以看到,objc_object中,只是保存了一個(gè)Class類型的isa。這里看不懂不要怕,先記著,對(duì)象中就是保存了一個(gè)指向Objective C中對(duì)應(yīng)類的指針。
Class/objc_class
- Class
指向Objective C類對(duì)象(objc_class)的一個(gè)指針
底層定義
typedef struct objc_class *Class;
- 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;
/* Use `Class` instead of `struct objc_class *` */
可以看到,這就是類對(duì)象結(jié)構(gòu)體的定義,細(xì)心的同學(xué)可能發(fā)現(xiàn)了類對(duì)象里仍然有一個(gè)指針Class isa,先記著,這個(gè)isa指向的是類元對(duì)象。這個(gè)我會(huì)在下一篇文章里詳細(xì)闡述
IMP
- IMP-指向?qū)嶋H執(zhí)行函數(shù)體的函數(shù)指針
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif
可以看到,這個(gè)函數(shù)體前兩個(gè)參數(shù)是 id(消息接受者,也就是對(duì)象),以及SEL(方法的名字)
method/objc_method
- method - 指向Objective C中的方法的指針
typedef struct objc_method *Method;
其中
struct objc_method {
SEL method_name OBJC2_UNAVAILABLE;
char *method_types OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE;
} OBJC2_UNAVAILABLE;
_cmd
SEL 類型的一個(gè)變量,Objective C的函數(shù)的前兩個(gè)隱藏參數(shù)為self 和 _cmd
Ivar
- ivar - objective C中的實(shí)例變量
typedef struct objc_ivar *Ivar;
可以看到變量的內(nèi)存模型
struct objc_ivar {
char *ivar_name OBJC2_UNAVAILABLE;
char *ivar_type OBJC2_UNAVAILABLE;
int ivar_offset OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
這篇文件是轉(zhuǎn)載過(guò)來(lái),后續(xù)重新編輯。
作者:黃文臣
來(lái)源:CSDN
原文:https://blog.csdn.net/Hello_Hwc/article/details/49682857
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!