Runtime定義:
是一套匯編翰撑,C,C++組成的一套API,給OC提供運(yùn)行時(shí)特性罩缴。
運(yùn)行時(shí)
將代碼,系統(tǒng)庫等裝載到內(nèi)存
編譯時(shí)
將我們寫的高級語言翻譯成二進(jìn)制語言
OC對象的本質(zhì):結(jié)構(gòu)體(繼承于結(jié)構(gòu)體)
OC方法的本質(zhì):發(fā)送消息
消息的組成:
((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("run"));
// void *)objc_msgSend)((id)p 消息接受者
// sel_registerName("run") 方法編號 --- name
- 對象方法存在類中
- 類方法存在元類中
- 對象方法和類方法在其對象中都是以實(shí)例方法存在
runtime底層代碼分析
objc_msgSend消息尋找方法實(shí)現(xiàn)
會首先從cache_t 中尋找层扶;如果沒有找到箫章,會有一個(gè)慢速的,通過C方法尋找镜会;否則炉抒,就是一個(gè)復(fù)雜的過程,找到方法實(shí)現(xiàn)并且存儲進(jìn)cache_t中稚叹。
runtime底層中為什么要使用匯編焰薄?
- 快拿诸。我們知道C還會進(jìn)行編譯成匯編,所以匯編是更快的塞茅;
- 但是真正更為重要的原因是亩码,用C實(shí)現(xiàn)不了。因?yàn)镃是無法保留指針野瘦,然后隨時(shí)跳轉(zhuǎn)到任意的指針描沟。我們寫C方法的時(shí)候,是一定要知道函數(shù)地址的鞭光,否則編譯不通過就是這個(gè)原因吏廉。于是使用匯編,將一個(gè)指針保留惰许,等待需要的時(shí)候才指定想要的地址席覆。匯編通過寄存器達(dá)到想要的實(shí)現(xiàn)。
匯編部分
C/C++部分
動態(tài)方法解析
消息轉(zhuǎn)發(fā)
應(yīng)用
動態(tài)創(chuàng)建類汹买,并且添加屬性和方法
Class superClass = [UIViewController class];
cls = objc_allocateClassPair(superClass, clsName, 0);
class_addIvar(cls, "ending", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
class_addIvar(cls, "show_lb", sizeof(UILabel *), log2(sizeof(UILabel *)), @encode(UILabel *));
objc_registerClassPair(cls);
Method method = class_getInstanceMethod([self class], @selector(lg_instancemethod));
IMP methodIMP = method_getImplementation(method);
const char *types = method_getTypeEncoding(method);
BOOL rest = class_addMethod(cls, @selector(viewDidLoad), methodIMP, types);