最近閒了下來,有時間了就研究一下runtime的運行機制,以前作開發的時候一直也沒有特別關注這個東西,只是知道有,可是不多去刻意的使用,研究的不是很深,簡單說一下吧,有錯誤的地方歡迎你們隨時指正.html
Objective-C Runtime 是什麼?編程
Objective-C 的 Runtime 是一個運行時庫(Runtime Library),它是一個主要使用 C 和彙編寫的庫,爲 C 添加了面相對象的能力並創造了 Objective-C。這就是說它在類信息(Class information) 中被加載,完成全部的方法分發,方法轉發,等等。Objective-C runtime 建立了全部須要的結構體,讓 Objective-C 的面相對象編程變爲可能數組
(上段引用自:http://www.cocoachina.com/iOS/20141008/9844.html)xcode
以前對於runtime的理解,只是僅僅侷限於對變量或者對象的類型由編譯時推遲到了運行時.好比定義一個NSString類型的變量,語句這麼寫緩存
則會輸出函數
很明顯,當咱們定義了NSSring類型的變量str以後,其類型並無肯定下來,而是等到運行的時候,才肯定了對象的體現.學習
可是這並非今天要說的重點,若是運行時只有這點功能的話,那麼蘋果的工程師也就太大材小用了,運行時最重要的做用仍是體如今消息機制上.優化
咱們都知道,OC是一門面向對象的語言,不少時候在解決問題的時候都是站在面向對象的角度來考慮.好比我要建設一座房子,我並不須要考慮如何去建設,只須要考慮把這個任務分給幾我的去作,好比A製做窗戶,B製做門,C製做屋頂….我只須要考慮把這些任務分配給幾我的去作,至於他們是怎麼實現的我並不須要考慮.就拿給A分配任務來講,調用下面的方法:spa
這樣就把任務分配給了A,那麼在運行時編譯後的語句則以下所示.net
objc_msgSend(aPeple,@selector(makeWindow));
將[aPeople makeWindow]轉化爲了objc_msgSend函數的格式,這個函數有兩個參數,第一個參數就是咱們建立的對象,第二個參數是一個方法選擇器,使用@selector(makeWindow)來生成一個SEL,SEL就是對方法的一種包裝。包裝的SEL類型數據它對應相應的方法地址,找到方法地址就能夠調用方法.接着根據SEL去aPeople歸屬的class裏去查找,咱們先看一下OC中class的結構,其實Class就是一個指向結構體的指針,其內容以下:
如下是對參數的具體詳解,其代碼部分來自runtime的源代碼,引自:http://blog.csdn.net/uxyheaven/article/details/38113901
(引用結束)
調用objc_msgSend函數的時候,首先會使用@selector(makeWindow)產生的SEL去class的cache裏去查找函數的指針,若是在這裏找到的話,則直接調用;若是沒有找到的話,則去methodList裏查找函數的指針,找到的話直接調用,沒有找到的話則去super_class裏查找,找到後將該函數指針緩存到cache裏方便下次的查找.
以上就是我對運行時的消息發送機制的瞭解,如今瞭解的仍是比較淺,不夠深刻,等之後進一步學習的時候,會將更多的內容分享出來.下一篇文章將會介紹runtime在開發中常常用到的地方.