Category的實現(xiàn)原理啰脚。
-
Category
編譯之后的底層結構是struct category_t
询张,里面存儲著分類的實例方法
、類方法
戒幔、屬性
吠谢、協(xié)議信息
- 在程序運行的時候,
Runtime
會將Category
的數(shù)據诗茎,合并附加到類信息中(class
對象工坊、meta-class
對象) - PS1:
Runtime
將分類的方法放在原來的方法的前面,因此分類的方法優(yōu)先級更高敢订,所以如果有重名的方法王污,會優(yōu)先調用分類的方法 - PS2:如果多個分類有重名的方法,【后】編譯的分類的方法優(yōu)先級更高楚午,因為Runtime里面的方法列表附加操作的順序是下標從大到小進行的昭齐,越往后越靠前
- PS3:在
Tatgets
->Build Phases
->Compile Sources
中可以控制編譯順序,編譯是從上到下的順序矾柜,想調用的優(yōu)先級高的就往下放
Category和Class Extension的區(qū)別是什么阱驾?
-
Class Extension
在編譯的時候,它的數(shù)據就已經包含在類信息中 -
Category
是在運行時怪蔑,才會將數(shù)據合并到類信息中
Category中有l(wèi)oad方法嗎里覆?load方法是什么時候調用的?load方法能繼承嗎缆瓣?
- 有喧枷。
-
load
方法在Runtime
加載類、分類的時候調用 -
load
方法可以繼承捆愁,在子類沒有重寫load
方法割去,主動去調用load
方法(消息發(fā)送機制)時會調用父類的load
方法,說明是有繼承關系的昼丑,但是一般情況下不會主動去調動load
方法呻逆,都是讓系統(tǒng)自動調用(在Runtime
加載時是直接拿到load
方法的地址去調用,之后手動調用時其實就是利用消息發(fā)送機制:子類沒有load
方法就會去父類的方法列表里面找)
load菩帝、initialize方法的區(qū)別是什么咖城?它們在Category中的調用的順序茬腿?以及出現(xiàn)繼承時它們之間的調用過程?
- 區(qū)別:
- 調用方式
load
是根據函數(shù)地址直接調用
initialize
是通過objc_msgSend
調用
- 調用時刻
load
是Runtime
加載(所有參與編譯的)類宜雀、分類的時候調用切平,只會調用1次
initialize
是類第一次接收到消息的時候調用,每一個類只會調用initialize
一次辐董,但父類的initialize
方法可能會被調用多次(例如:子類和子類的分類都沒有實現(xiàn)initialize
方法時就會去調用父類的initialize
方法)
- 調用順序
load
:
先調用類的load
先編譯的類悴品,優(yōu)先調用load
調用子類的load
之前,會先調用父類的load
再調用分類的load
先編譯的分類简烘,優(yōu)先調用load
initialize
:
調用父類的initialize
(初始化)
再調用子類的initialize
(初始化)
可能最終調用的是父類的
initialize
(子類沒有實現(xiàn)initialize
)
Category能否添加成員變量苔严?如果可以,如何給Category添加成員變量孤澎?
- 不能直接給
Category
添加成員變量届氢,但是可以間接實現(xiàn)Category
有成員變量的效果關聯(lián)對象
。