一、Category簡介
category是Objective-C 2.0之后添加的運行時特性,主要的作用就是為已經存在的類添加方法。它可以讓類的實現分布在幾個不同的文件里,有如下優(yōu)點
一是減少單個文件的大小,
二是可以把不同的功能分別放在不同的category里,
三,方便多個開發(fā)者維護,
四,可以按需求加載不同的category.
五,聲明私有方法
注意:category只可以給類添加方法或屬性(只有setter和getter方法,沒有變量),但是添加不了變量(ivar)
二、Category和Extension的區(qū)別
extension和category看起來和使用起來很像,但是extension和category完全是兩個東西。extension在編譯期處理,它本身就是類的一部分,在編譯的時候,和頭文件里的@interface以及實現文件里的@implemention一起形成一個完整的類,它跟類一起加載,一起釋放,所以extension可以添加變量。而category是運行時行為。Extension一般用來隱藏類的私有信息,必須知道類的源碼可以為類添加extention,而category則不用.
三、Category結構
所有的oc類和對象,在runtime層都是一個結構體,category也一樣,在runtime時,category也是一個結構體category_t,它的結構如下所示:
struct category_t {
const char *name;
classref_t cls;
struct method_list_t *instanceMethods;
struct method_list_t *classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta) {
if (isMeta) return nil; // classProperties;
else return instanceProperties;
}
};
結構體里包含了類、類的名字、實例方法列表、類方法列表、協(xié)議列表、屬性等
四、Category實現原理
插件不靈了。。新代碼塊插件比較麻煩,下面就不貼源碼了,感興趣的同學可以自己翻下源碼
1.運行時,把category的實例方法、協(xié)議及屬性添加到類上
2.運行時,把catetgory的類方法和協(xié)議添加到類的metaclass上(元類)
3.category添加方法列表的時候,先獲取類的消息列表,然后依次追加
4.方法調用時(即消息響應時),獲取實例的方法列表,倒序查找方法,然后響應
5.類方法同上
五、幾個注意點
Category可以添加方法、屬性,但是不可以添加變量,添加屬性也是只有setter跟getter,原因是:oc里用于給類添加變量的方法lass_addIvar(),只有在構建一個類的過程中才可以調用,一旦完成類的定義,就不能調用添加變量了,當然apple也嘗試過可以添加變量,但是沒有實施,源碼里有類似的代碼,但是被注釋掉了。
category的方法被加到類或實例中的時候,是加在方法列表的后面的,但是響應的時候,是從方法列表里倒序查找的,所以,后加載的方法會先響應,如果category中的方法跟類中重復,會響應category中的方法,如果兩個category都有此方法,那么后加載的會響應,當然,可以通過獲取方法列表,正序取出方法來完成響應。
同理,多個.a里如果有相同類的category中方法重名,跟第2條同理
歡迎大家提出寶貴意見