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
@interface BaseClass (Private) //类的分类
- (void)privateMethod; @end
然而,类的私用方法通常是希望存在于类的@implementation块中,而不是像上面的Category的方法那样存在于独立的@interface块中。事实上,Category仅仅是弥补了Objective-C缺少public/private限定的不足。
真正的问题是Objective-C编译器会认为在Category中声明的方法将会在别处实现,所以编译器并不会尝试确认它们是不是真的都被实现了。也就是说,开发者声明的方法有可能并未实现,而且编译器也不会有什么警告。编译会以为它们将在别的地方或独立的文件中实现。
使用Exteionsion,在其中声明的属性和方法的实现将放在Class的@implementation区块中。否则,编译器就会报错。
ExtensionClass.h
@interface ExtensionClass : NSObject //类的声明
@property (retain, readonly) float value; //声明公开只读属性 @end
ExtensionClass.m
@interface ExtensionClass() //类的扩展(Extension)
@property (retain, readwrite) float value; //1、声明私有可读写属性;而在类的声明中是同名的公开只读属性 - (void)privateMethod; //2、声明私有方法
@end @implementation ExtensionClass //类的实现 // 实现声明在头文件或父类中的公开方法,或者声明在扩展中的私有方法
- (void)privateMethod {
// implement private method here;
} @end
Extension和Category看起来相似,其实不同
由于Extension和Category的语法很相似,所以Extension常常被误解为一个匿名的Category,但是它们的目的和行为却是不同的。