班级扩展与班级类别


82

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

还有哪些其他区别?何时应该在类别扩展上使用类别?


类别是实际代码。它们就是您向类添加功能的方式。扩展(在非常笼统的意义上)更像是语法糖,向其他程序员传达有关隐私等的某些想法。扩展名不包含代码,也不是代码。
Fattie 2013年

对于扩展,因为它们是在斯威夫特使用,看到这个问题:stackoverflow.com/questions/24142829/...
Suragch

Answers:


91

主要区别在于,通过扩展,编译器将期望您在main内实现方法@implementation,而对于类别,则具有单独的@implementation块。因此,您几乎应该只在主.m文件的顶部使用扩展名(顺便说一句,您应该关心ivars的唯一位置)-扩展名就是这样。


41
扩展最适合您要在.m文件中声明的私有方法。我一直都用它。当您想将方法分为不同的部分(类别:)时,或者要将代码添加到未创建的现有类中时,类别更有用。
jtbandes

1
您还可以使用属性添加其他存储,例如类扩展。
Paul.s 2011年

23
类扩展也经过专门设计,以允许财产在公共readonly和私人场所公开readwrite。类别无法做到这一点(有意识的设计选择)。
bbum

为什么Google使用类别来实现私有方法而不是扩展?例如code.google.com/p/gdata-objectivec-client/source/browse/trunk/…–
瑞安(Ryan)

扩展要求所有方法都必须在@implementation块中实现,并且还提供了变量的增强功能。但是我们基本上是在尝试使用一些私有方法而不是使用私有变量,因此在这种情况下,我们更喜欢使用类别而不是扩展
Ankit Thakur 2012年

29

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

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

@interface ClassName ()
@end

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

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

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

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

使用班级扩展隐藏私人信息

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

例如,XYZPerson类可以添加一个名为uniqueIdentifier的属性,该属性旨在跟踪诸如美国的社会保险号之类的信息。

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

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

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

@property (readwrite) NSString *uniqueIdentifier;

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


7

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

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


“必须在主实现块中声明。” ->必须在主要实现模块中“实现”
Fawkes

谢谢,我已经修改了。
Julie Yu

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.