iOS開發之旅--_isa和_imp指針

iOS開發之旅--_isa和_imp指針

    

1、回顧_isa指針程序員

以前談到過isa指針,isa指針是一個指向所屬類的指針,它標註着一個實例對象的真實類型。緩存

在Object-C中消息機制是依靠objc_msgSend()這個函數發送消息,函數

objc_msgSend含兩個參數:receiver、selector。即:objc_msgSend(receiver, selector);測試

而objc_msgSend經過isa指針,找到實例對象所屬的類,也就找到了其所有父類,以下圖所示:spa

一個方法被調用要通過的真實步驟是這樣的:當我門向一個對象發送消息去調用他的方法時,objc_msgSend會根據該實例對象的isa指針去查找該對象的類,而後去查找該類的disptach table中的selector,若是找不到就會依次向上查找它的父類,並在其父類的dispatch table中查找相應的selector,直到NSObject類。一旦找到該selector,objc_msgSend會根據dispatch table中內存地址去調用該selector。這樣實現message和selector在執行階段的動態綁定。爲了提升這種查找轉發的效率。系統會把全部的selector內存地址和調用過的selector的內存地址緩存起來。而經過類的形式劃分不一樣的緩存區域。每個類的緩存區域會包括本身的selector和繼承自父類的selector,在objc_msgSend去查找disptach table前,會先去檢查該類的緩存。若是緩存命中,就直接調用selecotr。指針

2、瞭解_imp指針code

imp是implementation的縮寫,顧名思義imp指針是指向selector的具體實現的指針。在瞭解IMP指針以前,來探討一個問題,如今需求是在不影響層級結構和儘可能少改動的狀況下,讓項目中全部viewController的ViewDidLoad方法中打印本身的類型。瞭解Runtime的同窗,可能會想到對象

method_exchangeImplementations(Method m1, Method m2)blog


這種方式很輕鬆的實現了我門的需求,可是做爲一個優雅的程序員,就要作優雅的事情。下面就來imp指針。繼承

首先要配置工程

進行以下配置:

 

配置完成,直接上代碼:

 

使用imp指針更改方法實現成功。這樣作比上一種方式更加優雅。

 

接下來探討一下method_exchangeImplementations(Method m1, Method m2)方法的實現原理:

從imp指針的地址打印來看貌似這個方法是將兩個方法的imp指針作了互換。

 

通過這麼多代碼的測試,最終印證的仍是那句話,imp指針是指向selector具體實現的指針。

附加一下真實imp的具體定義:

相關文章
相關標籤/搜索