1.Runtime 是什么?
Runtime是用來動態(tài)創(chuàng)建類和對象,進(jìn)行消息發(fā)送和轉(zhuǎn)發(fā)的一套機(jī)制撞鹉。
2.Runtime 的運(yùn)行原理逆日?
要提運(yùn)行原理,先要解釋一下類的結(jié)構(gòu)奠滑。
每個(gè)類都包含:isa指針丹皱,指向了MetaClass。super_class 父類宋税、ivars(成員變量)摊崭、cache(緩存)、協(xié)議列表和method_list(方法列表)等杰赛。
消息:
OC代碼 [receiver message] ? 編譯后成 ?[objc_msgSend(receiver,selector)]?
// 除了編譯成objc_msgSend 外還有 objc_msgSendSuper 用super調(diào)用方法直接去父類找 以及objc_msgSend_stret 和 objc_msgSendSuper_stret?
當(dāng)一條OC代碼轉(zhuǎn)化成消息呢簸,首先找到接受者receiver,在它的cache中找selector,如果沒找到再到method_list中找乏屯,如果沒找到會沿著isa指針往metaClass中找根时,如果在Class中沒找到的話就會去superClass中找一直找到。如果找到的話辰晕,會把方法存到Cache中蛤迎,下次運(yùn)行的時(shí)候就不用一層層往上找了。如果在rootClass中都沒找到的話含友。在消息報(bào)錯(cuò)之前會還有機(jī)會處理這條消息替裆。
在消息報(bào)錯(cuò)之前校辩,如果你重寫了
+(Bool)resolveInstanceMethod:(SEL)sel 或者 +(Bool)resolveClassMethod:(SEL)sel ?
// 動態(tài)提供添加方法 ?一般會在里面調(diào)用class_addMethod 添加方法來處理消息。
那么可以在這個(gè)方法里面處理消息辆童,如果沒有處理則會給對象發(fā)送一條fowardInvocation消息
你可以在-(void)forwardInvocation:(NSInvocation *)anInvocation 中把消息給轉(zhuǎn)發(fā)給能處理的對象宜咒。 ?
NSInvocation 對象包含了原來的消息和傳遞的參數(shù)。
3.Runtime 能做什么把鉴?
遍歷類故黑,找私有成員變量、私有方法纸镊,給Category添加成員變量倍阐、對library進(jìn)行一些操作等。具體的方法參:官方文檔
有關(guān) Method Swizzling逗威。
Method Swizzling 簡單來說就是修改了Method(包含SEL,IMP的結(jié)構(gòu)體) 的 IMP(一個(gè)指執(zhí)行方法的函數(shù)指針)峰搪。在消息傳達(dá)時(shí),根據(jù)receiver找到對應(yīng)的Selector后,它會根據(jù)Selector對應(yīng)的IMP然后去找到方法凯旭。而Method Swizzling 其實(shí)就是修改了Seletor對應(yīng)的IMP概耻。
你可以通過重寫或者替換掉某些方法的IMP來實(shí)現(xiàn)特定的功能。
比如:
void method_exchangeImplementations (Method m1, Method m2) ?
// 交換兩個(gè)Method 的IMP
更多的方法可以查看官方文檔
有關(guān)Method Swizzling更詳細(xì)的文章:http://nshipster.com/method-swizzling/
參考文檔: