標籤:
Objective-C 2.0增加了Class Extension用於解決兩個問題:
- 可聲明私人可讀寫的屬性,而在類的聲明中是同名的公開唯讀屬性,從而來支援公開唯讀、私人可讀寫的屬性
- 可聲明私人方法;允許一個對象可以擁有一個私人的@interface,且可由編譯器驗證
公開唯讀、私人可寫的屬性(Publicly-Readable, Privately-Writeable Properties)
實現一個不可變(immutable)的資料結構通常有一個好處是外部代碼不能用setter方法修改對象的狀態。然而,可能又希望它在內部又是一個可寫的屬性。Extension可以做到這一點:
在類的擴充中聲明一個屬性為私人可讀寫,而在類的聲明中定義的同名屬性是公開唯讀。這樣,對外部代碼而言,該屬性將是唯讀,而內部代碼卻可以使用它的setter方法。
私人方法(Private Method)
Objective-C 2.0以前,若要定義私人方法,通常是在實現檔案中聲明一個"Private" Category:
BaseClass+Private.h
1 @interface BaseClass (Private) //類的分類 2 - (void)privateMethod;3 4 @end
然而,類的私用方法通常是希望存在於類的@implementation塊中,而不是像上面的Category的方法那樣存在於獨立的@interface塊中。事實上,Category僅僅是彌補了Objective-C缺少public/private限定的不足。
真正的問題是Objective-C編譯器會認為在Category中聲明的方法將會在別處實現,所以編譯器並不會嘗試確認它們是不是真的都被實現了。也就是說,開發人員聲明的方法有可能並未實現,而且編譯器也不會有什麼警告。編譯會以為它們將在別的地方或獨立的檔案中實現。
使用Exteionsion,在其中聲明的屬性和方法的實現將放在Class的@implementation區塊中。否則,編譯器就會報錯。
ExtensionClass.h
1 @interface ExtensionClass : NSObject //類的聲明 2 @property (retain, readonly) float value; //聲明公開唯讀屬性3 4 @end
ExtensionClass.m
1 @interface ExtensionClass() //類的擴充(Extension) 2 @property (retain, readwrite) float value; //1、聲明私人可讀寫屬性;而在類的聲明中是同名的公開唯讀屬性 3 4 - (void)privateMethod; //2、聲明私人方法 5 @end 6 7 @implementation ExtensionClass //類的實現 8 9 // 實現聲明在標頭檔或父類中的公開方法,或者聲明在擴充中的私人方法 10 - (void)privateMethod { 11 // implement private method here; 12 } 13 14 @end
Extension和Category看起來相似,其實不同
由於Extension和Category的文法很相似,所以Extension常常被誤解為一個匿名的Category,但是它們的目的和行為卻是不同的。
Objective-C文法之擴充(Extension)的使用