category結(jié)構(gòu)體
typedef struct category_t {
const char *name; // 類名
classref_t cls; // 類
struct method_list *instanceMethods; // 實(shí)例方法列表
struct method_list *classMethods; // 類方法列表
struct protocol_list_t *protocols; // protocol
struct property_list_t *instanceProperties; // 添加的所有屬性
} category_t;
從category的定義可以看出category可以添加實(shí)例方法,類方法,實(shí)現(xiàn)協(xié)議,添加屬性,不可添加實(shí)例變量
category
為已經(jīng)存在的類添加方法
在運(yùn)行期決定,無(wú)法添加實(shí)例變量,因?yàn)樵谶\(yùn)行期,對(duì)象的內(nèi)存布局已經(jīng)確定,如果添加實(shí)例變量就會(huì)破壞類的內(nèi)部布局。
category的方法沒有完全替換原來(lái)類已經(jīng)有的方法,也就是說(shuō)如果category和原來(lái)的類都有methodA,那么category附加完之后,類的方法列表里會(huì)有兩個(gè)methodA
category的方法被放到了新方法列表的前面,runtime在查找方法的時(shí)候是順序查找,這樣會(huì)先找到category的方法,然后直接返回。
如果兩個(gè)category里都有methodA,要看compile sources 里的文件加載順序,哪個(gè)在后執(zhí)行哪個(gè)的methodA

category0.png
extension
在編譯期決定,它就是類的一部分,在編譯期和頭文件里的@interface以及實(shí)現(xiàn)文件的@implement一起形成一個(gè)完成的類,它伴隨類的產(chǎn)生而產(chǎn)生,亦隨之一起銷亡。
extension一般用來(lái)隱藏類的私有信息,你必須有一個(gè)類的源碼才能為一個(gè)類添加extension.所以你無(wú)法為系統(tǒng)的類比如NSString添加extension.