分類和擴(kuò)展
?? ? 類別允許您將方法添加到現(xiàn)有的類—甚至添加到您沒(méi)有源的類。Categories是一個(gè)強(qiáng)大的特性,它允許您擴(kuò)展現(xiàn)有類的功能构罗,而不需要子類化。通過(guò)使用類別智玻,您還可以在多個(gè)文件中分發(fā)您自己的類的實(shí)現(xiàn)遂唧。類擴(kuò)展類似,但是允許在主類@interface塊之外的位置為類聲明額外的api
?? ? 向類中添加方法
?? ? 您可以通過(guò)在類名下的接口文件中聲明方法吊奢,并在同名的實(shí)現(xiàn)文件中定義方法盖彭,從而向類中添加方法。類別名稱表示方法是對(duì)在別處聲明的類的添加事甜,而不是新類谬泌。但是,不能使用類別向類中添加其他實(shí)例變量逻谦。
?? ? 類別添加的方法成為類類型的一部分。例如陪蜻,添加到類別中的NSArray類中的方法包含在編譯器期望NSArray實(shí)例在它的指令表中具有的方法中邦马。但是,在子類中添加到NSArray類的方法不包括在NSArray類型中宴卖。(這只對(duì)靜態(tài)類型的對(duì)象很重要滋将,因?yàn)殪o態(tài)類型是編譯器了解對(duì)象類的唯一方法。)
?? ? Category方法可以做類中定義的方法可以做的任何事情症昏。在運(yùn)行時(shí)随闽,沒(méi)有區(qū)別。類添加到類中的方法由類的所有子類繼承肝谭,就像其他方法一樣掘宪。
?? ? 類接口的聲明看起來(lái)非常像類接口聲明——除了類名后面的括號(hào)中列出了類名蛾扇,而沒(méi)有提到超類。除非它的方法不訪問(wèn)類的任何實(shí)例變量魏滚,否則類必須為它擴(kuò)展的類導(dǎo)入接口文件:
?? ? #import "ClassName.h"
?? ? @interface ClassName ( CategoryName )
?? ? //方法聲明
?? ? @end
?? ? 注意镀首,類別不能為類聲明額外的實(shí)例變量;它只包含方法。但是鼠次,類范圍內(nèi)的所有實(shí)例變量也屬于類別范圍更哄。這包括類聲明的所有實(shí)例變量,甚至包括聲明@private的實(shí)例變量腥寇。
?? ? 可以添加到類中的類別數(shù)量沒(méi)有限制成翩,但是每個(gè)類別名稱必須不同,并且每個(gè)類別名稱都應(yīng)該聲明和定義不同的方法集赦役。
?? ? 擴(kuò)展
?? ? 類擴(kuò)展類似于匿名類別捕传,只是它們聲明的方法必須在對(duì)應(yīng)類的主@implementation塊中實(shí)現(xiàn)。使用Clang/LLVM 2.0編譯器扩劝,還可以在類擴(kuò)展中聲明屬性和實(shí)例變量庸论。
?? ? 類擴(kuò)展的一個(gè)常見(jiàn)用途是重新聲明屬性,該屬性公開(kāi)聲明為只讀棒呛,私有聲明為readwrite:
?? ? @interface MyClass : NSObject
?? ? @property (retain, readonly) float value;
?? ? @end
?? ? // 私有擴(kuò)展名聂示,通常隱藏在主實(shí)現(xiàn)文件中。
?? ? @interface MyClass ()
?? ? @property (retain, readwrite) float value;
?? ? @end
?? ? 注意(與類別相反)第二個(gè)@interface塊的括號(hào)中沒(méi)有給出名稱簇秒。
?? ? 通常鱼喉,一個(gè)類有一個(gè)公開(kāi)聲明的API,然后又有一些單獨(dú)聲明的方法趋观,僅供類或類所在的框架使用扛禽。類擴(kuò)展允許您在主類@interface塊之外的位置為類聲明其他必需的方法,如下例所示:
?? ? @interface MyClass : NSObject
?? ? - (float)value;
?? ? @end
?? ? @interface MyClass () {
?? ? float value;
?? ? }
?? ? - (void)setValue:(float)newValue;
?? ? @end
?? ? @implementation MyClass
?? ? - (float)value {
?? ? return value;
?? ? }
?? ? - (void)setValue:(float)newValue {
?? ? value = newValue;
?? ? }
?? ? @end
?? ? 方法的實(shí)現(xiàn)必須出現(xiàn)在類的主@implementation塊中(您不能在類別中實(shí)現(xiàn)它)皱坛。如果不是這樣编曼,編譯器會(huì)發(fā)出警告,說(shuō)明它無(wú)法找到setValue:的方法定義剩辟。