ios底層(一)Category的本質,load,initialize方法的調用順序

1.Category底層結構,如下

2.使用指令從編譯後的c++代碼,也可以看出是把在分類中寫的方法都賦值給了結構體

將Objective-C代碼轉換爲C\C++代碼

xcrun -sdk iphoneos clang  -arch  arm64 -rewrite-objc  OC源文件  -o  輸出的CPP文件

如果需要鏈接其他框架,使用-framework參數。比如-framework UIKit

第一張圖中圈的值賦值給了第二張的結構體屬性裏。

3.分析Category怎麼把方法合併到類中的。

是通過dyld裝載程序,初始化runtime環境的時候加載到類對象裏

直到最後調用到如下方法

上圖中圈中2行代碼做的事情就是把分類的方法列表加到原始類的方法列表前面。

所以最終會導致,對象調用方法時,先找到分類的方法進行調用。

也就是我們常說的分類方法會“覆蓋”原來類的方法的現象,但實際上並不是覆蓋,而是因爲分類方法被添加在了前面。

因爲消息機制isa在查找方法的時候找到就直接調用了,後面不會再管了。

 

4.我們所寫的就分類的方法,如果重名的話,會由編譯順序決定調用哪一個。

還有一點要注意就是寫靜態庫裏other linker flags 設置成 -all_load。

5.+load方法的調用

也是在dyld裝載程序,初始化runtime環境的時候調用的。所以代碼不管是否使用就會調用。

最後調用

而且兩個方法內部調用都是直接方法調用,沒有使用objc消息機制。

所以寫了原類,子類,分類.三個類裏面的+load都會依次調用。

6.+initialize方法, 首次使用類的時候只會調用一次

可以看到方法調用採取的是objc消息機制調用,

所以結果爲

比如寫了原類,子類,分類.三個類裏面的+initialize方法,只有原類、分類依次調用。

5和6的調用結果如下圖

PS:介於時間有限,本篇只列了一些重點並不算是詳細,

這裏還有另一篇比較詳細,可以參考https://blog.csdn.net/Bolted_snail/article/details/82258597

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章