85

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

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

4

4 回答 4

91

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

于 2011-08-21T03:26:51.410 回答
30

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

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

@interface ClassName ()
@end

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

与常规类别不同,类扩展可以将自己的属性和实例变量添加到类中。如果您在类扩展中声明一个属性,如下所示:

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

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

使用类扩展来隐藏私人信息

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

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

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

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

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

@property (readwrite) NSString *uniqueIdentifier;

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

于 2016-02-29T21:01:46.117 回答
7

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

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

于 2015-04-19T01:48:32.790 回答
0

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

于 2015-12-01T20:47:14.657 回答