3

类扩展的一个强大优势是,通过类扩展,您可以在头文件中声明一个只读属性,并在类扩展中将该属性覆盖为读写属性。如下所示:

//SomeClass.h

@interface SomeClass : NSObject
{
    NSInteger someInt;   //with modern runtime you can omit this line
}
@property (readonly) NSInteger someInt;
@end

//SomeClass.m
@interface SomeClass ()
@property (readwrite) NSInteger someInt;
@end

@implementation SomeClass
@synthesize someInt;
@end

但是,如果您使用现代运行时,您还可以在类扩展中声明一个全新的属性(如果没有,它也会为该属性生成一个 iVar)。

//SomeClass.h

@interface SomeClass : NSObject
{
}
@end

//SomeClass.m
@interface SomeClass ()
@property (readwrite) NSInteger someInt;
@end

@implementation SomeClass
@synthesize someInt;
@end

这是我的问题:我认为在类扩展中声明一个全新的属性在某种程度上会产生一些副作用。因为类扩展名不在头文件中,并且子类化该类的其他人可能不知道该“秘密属性”。如果他声明一个与该“秘密财产”同名的财产。而这个新属性的 getter 和 setter 方法将覆盖超类的。这不是问题吗?为什么现代运行时会允许这样的事情发生?

编辑我发布了关于这个主题的另一个问题,请查看: 在类扩展中声明新属性的风险(Ojbective-C),如何解决?

4

1 回答 1

6

我不认为在类扩展中声明一个新属性是不好的做法。我经常这样做。首先在标头中包含 readonly 属性的唯一原因是允许其他类获取该值,而只有您可以修改它。很多时候,该 ivar 应该与其他类无关,并且只是一个实现细节。因此,它在头文件中没有位置。

将此 ivar 实现为私有属性(仅在类扩展中声明的新属性)仍然有用,因为它可以为您抽象方便的内存管理样板代码。不幸的是,名称冲突在 Objective C 中只是生活中的一个事实。Apple 列出了一些非常清晰的命名约定供您遵循(或遵循)以防止与它们的方法名称发生冲突。如果您担心与您使用该私有属性无形地创建的 getter 和 setter 发生冲突,只需采用并痴迷于遵循一些您只使用的私有属性名称的命名约定在实现私有财产时使用过。那是你要用 Objective C 做的最好的事情,但我个人认为好处大于风险。

于 2011-04-12T18:42:08.977 回答