iOS-Category詳解

OC中提供的category特性可以讓我們動(dòng)態(tài)的為現(xiàn)有類添加新的行為,以比繼承更為簡(jiǎn)潔的方法來(lái)對(duì)Class進(jìn)行擴(kuò)展,無(wú)需創(chuàng)建對(duì)象類的子類就能為現(xiàn)有的類添加新方法,它可以為任何已經(jīng)存在的Class添加方法,包括那些蘋果沒(méi)有公開源代碼的類。

category作用

  1. 可以將類的實(shí)現(xiàn)分散到多個(gè)不同的文件或者不同的框架中,方便代碼的管理,也可以對(duì)框架提供類的擴(kuò)展

  2. 創(chuàng)建對(duì)私有方法的前向引用:
    Cocoa沒(méi)有任何真正的私有方法。只要知道對(duì)象支持的某個(gè)方法的名稱,即使該對(duì)象所在的類的接口中沒(méi)有該方法的聲明,你也可以調(diào)用該方法。不過(guò)這么做編譯器會(huì)報(bào)錯(cuò),但是只要新建一個(gè)該類的類別,在類別.h文件中寫上原始類該方法的聲明,類別.m文件中什么也不寫,就可以正常調(diào)用私有方法了。這就是傳說(shuō)中的私有方法前向引用。 所以說(shuō)cocoa沒(méi)有真正的私有方法。

  3. 向?qū)ο筇砑臃钦絽f(xié)議:
    蘋果官方文檔:

An informal protocol is a category on NSObject, which implicitly makes almost all objects adopters of the protocol. (A category is a language feature that enables you to add methods to a class without subclassing it.) Implementation of the methods in an informal protocol is optional. Before invoking a method, the calling object checks to see whether the target object implements it. Until optional protocol methods were introduced in Objective-C 2.0, informal protocols were essential to the way Foundation and AppKit classes implemented delegation.

也就是說(shuō):非正式協(xié)議是NSObject類(顯而易見,還包括它的子類)的類別,其所有的子類都含蓄地接受了這個(gè)協(xié)議。(類別是Objective-C的一個(gè)語(yǔ)言特點(diǎn),可以讓你在無(wú)需子類化的前提下為一個(gè)類增加方法。)非正式協(xié)議中的方法是否實(shí)現(xiàn)都是可選的,因此在調(diào)用非正式協(xié)議中的方法之前,需要去檢查對(duì)象類是否實(shí)現(xiàn)了它。在Objective-C2.0中引入可選的正式協(xié)議方法之前,非正式協(xié)議是Foundation和AppKit類實(shí)現(xiàn)委托的唯一方式。所謂的非正式協(xié)議就是類別,即凡是NSObject或其子類的類別,都是非正式協(xié)議。

category與extension的區(qū)別:

  • extension和category的創(chuàng)建方式一樣,只要在原來(lái)選擇Category的地方選擇Extension即可。但是,extension只會(huì)生成 .h 文件。之后我們可以在.h中直接添加成員變量、屬性和方法。而category是不能直接添加成員變量的(需要使用runtime添加)extension的常用形式不是創(chuàng)建一個(gè)單獨(dú)的文件,而是在實(shí)現(xiàn)文件中添加私有的成員變量、屬性和方法(比如創(chuàng)建Controller的時(shí)候XCode會(huì)自動(dòng)生成)
  • extension在編譯期決議,它就是類的一部分,在編譯期和頭文件里的@interface以及實(shí)現(xiàn)文件里的@implement一起形成一個(gè)完整的類,它伴隨類的產(chǎn)生而產(chǎn)生,亦隨之一起消亡。extension一般用來(lái)隱藏類的私有信息,你必須有一個(gè)類的源碼才能為一個(gè)類添加extension,所以你無(wú)法為系統(tǒng)的類比如NSString添加extension。
  • 類別在運(yùn)行期決議的,就類別和擴(kuò)展的區(qū)別來(lái)看,我們可以推導(dǎo)出一個(gè)明顯的事實(shí),擴(kuò)展可以添加實(shí)例變量,而類別是無(wú)法添加實(shí)例變量的(因?yàn)樵谶\(yùn)行期,對(duì)象的內(nèi)存布局已經(jīng)確定,如果添加實(shí)例變量就會(huì)破壞類的內(nèi)部布局,這對(duì)編譯型語(yǔ)言來(lái)說(shuō)是災(zāi)難性的)。

category為什么不能添加實(shí)例變量但可以添加屬性?

我們知道Objective-C類是由Class類型來(lái)表示的,它實(shí)際上是一個(gè)指向objc_class結(jié)構(gòu)體的指針。所以類其實(shí)就是一個(gè)結(jié)構(gòu)體,類別也是一樣:

typedef struct category_t {
    const char *name;  // 類的名字(名稱)
    classref_t cls; // 類(CLS)
    struct method_list_t *instanceMethods; // 類中所有給類添加的實(shí)例方法的列表
    struct method_list_t *classMethods; // 類中所有添加的類方法的列表
    struct protocol_list_t *protocols; // category實(shí)現(xiàn)的所有協(xié)議的列表
    struct property_list_t *instanceProperties; // category中添加的所有屬性
} category_t;

從類別的定義也可以看出類別的可以添加實(shí)例方法,類方法,甚至可以實(shí)現(xiàn)協(xié)議,添加屬性和不可以添加實(shí)例變量。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,621評(píng)論 1 32
  • (一)Category 1、什么是Category? category是Objective-C 2.0之后添加的語(yǔ)...
    叩首問(wèn)路夢(mèng)碼為生閱讀 724評(píng)論 0 11
  • (一)Category category是Objective-C 2.0之后添加的語(yǔ)言特性,別人口中的分類、類別其...
    小李龍彪閱讀 3,030評(píng)論 0 10
  • 一 類別的簡(jiǎn)介 在開發(fā)中有時(shí)會(huì)用到Category,類別有三個(gè)作用: (1)可以將類的實(shí)現(xiàn)分散到多個(gè)不同文件或多個(gè)...
    々莫等閑々閱讀 493評(píng)論 0 0
  • 把所有能夠工具化的東西都工具化。 人的很多行為都是動(dòng)物性控制人做出的選擇 調(diào)整自己,以送禮物的心態(tài)來(lái)對(duì)待所有的演講...
    骨木扣子閱讀 259評(píng)論 0 0

友情鏈接更多精彩內(nèi)容