iOS runtime的簡單理解

  最近閒了下來,有時間了就研究一下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

 

version  類的版本信息,默認爲0
info  供運行期使用的一些位標識
instance_size  該類的實例變量大小
ivars  成員變量的數組
 
  1. struct objc_ivar_list {  
  2.     int ivar_count;  
  3.     /* variable length structure */  
  4.     struct objc_ivar ivar_list[1];  
  5. }  
methodLists  方法定義的數組
  1. struct objc_method_list {  
  2.     struct objc_method_list *obsolete;  
  3.     int method_count;  
  4.     /* variable length structure */  
  5.     struct objc_method method_list[1];  
  6. }  
objc_cache   指向最近使用的方法.用於方法調用的優化.
  1. struct objc_cache {  
  2.     unsigned int mask /* total = mask + 1 */;  
  3.     unsigned int occupied;  
  4.     Method buckets[1];  
  5. };  
protocols 協議的數組
  1. struct objc_protocol_list {  
  2.     struct objc_protocol_list *next;  
  3.     long count;  
  4.     Protocol *list[1];  
  5. };  

(引用結束)

 

      調用objc_msgSend函數的時候,首先會使用@selector(makeWindow)產生的SEL去class的cache裏去查找函數的指針,若是在這裏找到的話,則直接調用;若是沒有找到的話,則去methodList裏查找函數的指針,找到的話直接調用,沒有找到的話則去super_class裏查找,找到後將該函數指針緩存到cache裏方便下次的查找.

 

      以上就是我對運行時的消息發送機制的瞭解,如今瞭解的仍是比較淺,不夠深刻,等之後進一步學習的時候,會將更多的內容分享出來.下一篇文章將會介紹runtime在開發中常常用到的地方.

相關文章
相關標籤/搜索