类扩展与类类别

时间:2011-08-21 03:23:37

标签: objective-c objective-c-category class-extensions

类扩展@interface Class ()功能更强大,可以将变量注入到类中。类别@interface Class (Category)不能。

还有什么其他差异,何时应该使用类别而不是类扩展?

4 个答案:

答案 0 :(得分:84)

主要区别在于,使用扩展名,编译器会期望您在主@implementation中实现方法,而对于类别,您有一个单独的@implementation块。因此,您几乎只应在主.m文件的顶部使用扩展名(这是唯一一个您应该关注ivars的地方,顺便提一下) - 它只是一个扩展名

答案 1 :(得分:24)

类扩展与类别有一些相似之处,但它只能添加到编译时拥有源代码的类中(类与类扩展同时编译)。类扩展声明的方法在原始类的@implementation块中实现,因此您不能在框架类上声明类扩展,例如Cocoa或Cocoa Touch类,如NSString。

声明类扩展的语法类似于类别的语法,如下所示:

@interface ClassName ()
@end

因为括号中没有给出名称,所以类扩展通常被称为匿名类别。

与常规类别不同,类扩展可以将自己的属性和实例变量添加到类中。如果在类扩展中声明属性,请执行以下操作:

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

恕我直言,最好将类扩展视为类的私有接口。主接口(在.h文件中)充当公共接口,用于定义类与其他类的行为合同。

使用附加信息类隐藏隐私信息

类扩展通常用于使用其他私有方法或属性扩展公共接口,以便在类本身的实现中使用。例如,通常在接口中将属性定义为只读,但在实现上方声明的类扩展中为readwrite,以便类的内部方法可以直接更改属性值。

例如,XYZPerson类可能会添加一个名为uniqueIdentifier的属性,用于跟踪美国社会安全号码等信息。

通常需要大量的文书工作才能在现实世界中为个人分配唯一标识符,因此XYZPerson类接口可能会将此属性声明为readonly,并提供一些请求标识符的方法,例如:

@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

为了让XYZPerson类能够在内部更改属性,重新声明在类的实现文件顶部定义的类扩展中的属性是有意义的:

@property (readwrite) NSString *uniqueIdentifier;

注意:readwrite属性是可选的,因为它是默认值。为清晰起见,您可能希望在重新声明属性时使用它。

答案 2 :(得分:5)

类别是Objective-C语言功能,允许您向现有类添加新方法。扩展是类别的一种特殊情况,它允许您定义必须在主实现块中实现的方法。

私有声明可以在类扩展中,主要是一些属性,因为我们在调用它之前不需要声明方法。

答案 3 :(得分:0)

ios扩展类似于c#,java抽象类或接口
ios类别与c#类扩展类似