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