在Objective-C中,在类扩展中声明新属性是一种糟糕的做法吗?

在Objective-C中,在类扩展中声明新属性是一种糟糕的做法吗?,objective-c,properties,class-extensions,modern-runtime,Objective C,Properties,Class Extensions,Modern Runtime,类扩展的一个强大优势是,使用类扩展,您可以在头文件中声明一个只读属性,并将类扩展中的该属性重写为readwrite属性。如下图所示: //SomeClass.h @interface SomeClass : NSObject { NSInteger someInt; //with modern runtime you can omit this line } @property (readonly) NSInteger someInt; @end //SomeClass.m @i

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

//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)

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

编辑我发布了关于此主题的另一个问题,请查看:

我认为在类扩展中声明新属性不是一个坏习惯。我经常这样做。在头文件中首先包含readonly属性的唯一原因是允许其他类获取该值,而只有您可以修改它。通常情况下,ivar与其他类无关,只是一个实现细节。因此,它在头文件中没有位置


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

是的,这是一个很好的做法。不要害怕+回答得好。你也有苹果文档的url吗?@Martin:有。我编辑了答案以链接到它,出于好奇。@Johnathan我发布了关于这个主题的另一个问题,请查看:
//SomeClass.h

@interface SomeClass : NSObject
{
}
@end

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

@implementation SomeClass
@synthesize someInt;
@end