原文鏈接:http://blog.csdn.net/mumubumaopao/article/details/51924964
最近閑了下來,有時間了就研究一下runtime的運行機制,之前做開發(fā)的時候一直也沒有特別關注這個東西,只是知道有,但是很少去刻意的使用,研究的不是很深,簡單說一下吧,有錯誤的地方歡迎大家隨時指正.
Objective-C Runtime 是什么?
Objective-C 的 Runtime 是一個運行時庫(Runtime Library),它是一個主要使用 C 和匯編寫的庫,為 C 添加了面相對象的能力并創(chuàng)造了 Objective-C。這就是說它在類信息(Class information) 中被加載,完成所有的方法分發(fā),方法轉(zhuǎn)發(fā),等等。Objective-C runtime 創(chuàng)建了所有需要的結構體,讓 Objective-C 的面相對象編程變?yōu)榭赡?
之前對于runtime的理解,只是僅僅局限于對變量或者對象的類型由編譯時推遲到了運行時.比如定義一個NSString類型的變量,語句這么寫
則會輸出
很明顯,當我們定義了NSSring類型的變量str之后,其類型并沒有確定下來,而是等到運行的時候,才確定了對象的體現(xiàn).
但是這并不是今天要說的重點,如果運行時只有這點功能的話,那么蘋果的工程師也就太大材小用了,運行時最重要的作用還是體現(xiàn)在消息機制上.
我們都知道,OC是一門面向?qū)ο蟮恼Z言,很多時候在解決問題的時候都是站在面向?qū)ο蟮慕嵌葋砜紤].比如我要建設一座房子,我并不需要考慮如何去建設,只需要考慮把這個任務分給幾個人去做,比如A制作窗戶,B制作門,C制作屋頂….我只需要考慮把這些任務分配給幾個人去做,至于他們是怎么實現(xiàn)的我并不需要考慮.就拿給A分配任務來說,調(diào)用下面的方法:
這樣就把任務分配給了A,那么在運行時編譯后的語句則如下所示
objc_msgSend(aPeple,@selector(makeWindow));
將[aPeople makeWindow]轉(zhuǎn)化為了objc_msgSend函數(shù)的格式,這個函數(shù)有兩個參數(shù),第一個參數(shù)就是我們創(chuàng)建的對象,第二個參數(shù)是一個方法選擇器,使用@selector(makeWindow)來生成一個SEL,SEL就是對方法的一種包裝。包裝的SEL類型數(shù)據(jù)它對應相應的方法地址,找到方法地址就可以調(diào)用方法.接著根據(jù)SEL去aPeople歸屬的class里去查找,我們先看一下OC中class的結構,其實Class就是一個指向結構體的指針,其內(nèi)容如下:
以下是對參數(shù)的具體詳解,其代碼部分來自runtime的源代碼,引自:http://blog.csdn.net/uxyheaven/article/details/38113901
structobjc_ivar_list?{
intivar_count;
/*?variable?length?structure?*/
structobjc_ivar?ivar_list[1];
}
structobjc_method_list?{
structobjc_method_list*obsolete;
intmethod_count;
/*?variable?length?structure?*/
structobjc_method?method_list[1];
}
objc_cache指向最近使用的方法.用于方法調(diào)用的優(yōu)化.
structobjc_cache?{
unsignedintmask/*?total?=?mask?+?1?*/;
unsignedintoccupied;
Method?buckets[1];
};
structobjc_protocol_list?{
structobjc_protocol_list*next;
longcount;
Protocol*list[1];
};
調(diào)用objc_msgSend函數(shù)的時候,首先會使用@selector(makeWindow)產(chǎn)生的SEL去class的cache里去查找函數(shù)的指針,如果在這里找到的話,則直接調(diào)用;如果沒有找到的話,則去methodList里查找函數(shù)的指針,找到的話直接調(diào)用,沒有找到的話則去super_class里查找,找到后將該函數(shù)指針緩存到cache里方便下次的查找.
加入審核被拒交流群,一起交流審核上架經(jīng)驗吧~~ 群號:689757099