OC runtime_1(消息傳遞,消息轉(zhuǎn)發(fā))

運行時(runtime)系統(tǒng)是一個提供一系列公開函數(shù)接口以及數(shù)據(jù)結(jié)構(gòu)的動態(tài)鏈接庫

消息傳遞機制:


OC是動態(tài)語言,所有方法的調(diào)用都會通過runtime動態(tài)地轉(zhuǎn)換成消息發(fā)送,這個過程中就用到了相應(yīng)的運行時方法:

receiver:接受者,selector:本質(zhì)是方法名


(1) 在傳遞給接受者(實例對象)的過程中,需要通過對象的isa指針尋找“對象所屬的類對象”,在這之前,引入了“OC對象”的內(nèi)存布局:

OC對象包含一個isa指針,指向其所屬的類對象,同時包含其所有父類的實例變量。



(2) 接著,在其父類對象的方法列表中尋找方法以供調(diào)用,這里又引出了“類對象”中存放的內(nèi)容:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<1> ?實例對象的方法列表(方法名稱,IMP實現(xiàn),參數(shù)類型)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<2> ?成員變量列表

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<3> ?屬性列表



(3) 然后,因為類對象也是對象,所有也有isa指針,指向元對象。引入“元類對象”中存放的內(nèi)容:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <1>? 類方法列表 (方法名稱,IMP實現(xiàn),參數(shù)類型)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <2> ?superclass指針



(4) 實例對象,類對象,元對象通過isa指針關(guān)聯(lián),類對象和元對象通過superclass指針與父類關(guān)聯(lián),從而形成如下圖一樣的閉環(huán):

PS: ??<1> 根類是NSObject,它的superclass指針指向nil。

? ? ? ? ? <2> 所有元類對象的isa指針都指向根元類,根元類 ?isa指針指向自己,superclass指針指向NSObject。



(5) 接著(2)中,找完父類的方法列表,沒找到,會繼續(xù)找父類的父類,一直找到頂層的父類,如果沒有找到會拋出“unrecognized selector sent to XXX”異常。在這之前,runtime提供了三次拯救程序崩潰的機會:

? ? ? ? ? ?<1> Method resolution

? ? ? 你可以通過實現(xiàn) +resolveInstanceMethod: 以及?+resolveClassMethod: 方法以動態(tài)的實現(xiàn)一個指定實例的實例方法或者類方法。

PS: 一般說來,消息轉(zhuǎn)發(fā)機制?和?動態(tài)加載機制?是正交的。在轉(zhuǎn)發(fā)機制介入之前,一個類有機會動態(tài)的加載一個方法。


? ? ? ? ? ? <2> Fast forwarding

? ? ? ?如果對象實現(xiàn) -forwardingTargetForSelector:,runtime就會調(diào)用這個方法,給把這個消息轉(zhuǎn)發(fā)給其他對象的機會。


? ? ? ? ? ? <3> Normal forwarding

? ? ? ? 運行時發(fā)送 -methodSignatureForSelector: 消息獲得函數(shù)參數(shù)和返回值類型,如果返回nil,運行時會發(fā)送 -doesNotRecognizeSelector消息,然后拋出(5)中異常。如果返回了函數(shù)簽名,運行時就會創(chuàng)建一個NSInvocation對象并發(fā)送 -forwardInvocation: 消息給目標對象。


PS:

? ? ? ? 為了加速上述消息調(diào)用的過程。運行時系統(tǒng)會緩存它們使用過的方法名以及對應(yīng)的方法地址。這些緩存是針對每個類單獨緩存的,當然,這其中包含它自己定義的方法以及繼承自父類的方法。在搜索方法列表之前,消息傳遞路由會先檢查接收消息接收類的緩存(基于如果干過一次就很可能還會干下一次的理論)。如果方法名存在緩存中,消息傳遞只比直接的函數(shù)調(diào)用慢那么一點點。一旦一個程序已經(jīng)跑了足夠長的時間以“預(yù)熱”他的緩存,幾乎所有發(fā)送的消息就都可能被緩存了。緩存是根據(jù)程序運行時新消息的調(diào)用動態(tài)增長的。


引文:


? ? ? ??OC運行時編程指南

? ? ??《招聘一個靠譜的iOS》面試題參考答案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,775評論 0 9
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,636評論 33 466
  • 我們常常會聽說 Objective-C 是一門動態(tài)語言,那么這個「動態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,232評論 0 7
  • 一、Runtime簡介 Runtime簡稱運行時。OC就是運行時機制,也就是在運行時候的一些機制,其中最主要的是消...
    林安530閱讀 1,079評論 0 2
  • 原文出處:南峰子的技術(shù)博客 Objective-C語言是一門動態(tài)語言,它將很多靜態(tài)語言在編譯和鏈接時期做的事放到了...
    _燴面_閱讀 1,258評論 1 5