在Objective-C中,在类扩展中声明新属性是不好的实践吗?

时间:2022-05-17 10:28:54

One strong advantage of class extension is that with class extension you can declare a readonly property in the header file and override this property in class extension as readwrite property. Like below :

类扩展的一个强大优势是,通过类扩展,您可以在头文件中声明一个readonly属性,并将类扩展中的这个属性重写为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

But if you use a modern runtime ,you can also declare a totally new property in the class extension (which also generate an iVar for that property if there isn't).

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

//SomeClass.h

@interface SomeClass : NSObject
{
}
@end

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

@implementation SomeClass
@synthesize someInt;
@end

Here's my question : I think declare a totally new property in class extention is somehow has some side effects. Because class extension my not be in the header file and someone else who subclass the class may not know about that "secret property". And if he declare a property with the same name of that "secret property". And this new property's getter and setter method will override the super class's. Isn't this a problem?And why would modern runtime allow such thing happen?

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

EDIT I posted another question about this topic , please check it out: The risk of declare new propery in class extension (Ojbective-C) , how to solve it?

关于这个题目,我贴了另外一个问题,请查收:在类扩展(ojbeco - c)中申报新属性的风险,如何解决?

1 个解决方案

#1


6  

I don't think it's bad practice to declare a new property in a class extension. I do this with some frequency. The only reason to include the readonly property in the header in the first place is to allow other classes to get the value, while only you are allowed to modify it. Quite often, that ivar should be of no concern to other classes, and is an implementation detail only. As such, it has no place in the header file.

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

Implementing this ivar as a private property (a new property only declared in the Class Extension) is still useful, because of the convenient memory management boilerplate code it can abstract for you. Unfortunately, name collisions are just a fact of life in Objective C. Apple lays out some pretty clear naming conventions for you to follow (or not follow) to prevent collisions with their method names. If you're worried about collisions with the getters and setters you've invisibly created with that private property, just adopt and obsessively follow some naming convention for those private property names that you only ever use when implementing a private property. That's the best you're going to do with Objective C, but I personally think the benefits outweigh the risks.

将这个ivar实现为私有属性(仅在类扩展中声明的新属性)仍然很有用,因为它可以为您抽象内存管理样板代码。不幸的是,在Objective c中,名称冲突只是一个事实。Apple给出了一些非常清晰的命名约定,供您遵循(或不遵循),以避免与它们的方法名称发生冲突。如果您担心与您用私有属性创建的getter和setter之间的冲突,那么只需为实现私有属性时仅使用的私有属性名采用并痴迷地遵循一些命名约定。这是Objective - C的最佳效果,但我个人认为好处大于风险。

#1


6  

I don't think it's bad practice to declare a new property in a class extension. I do this with some frequency. The only reason to include the readonly property in the header in the first place is to allow other classes to get the value, while only you are allowed to modify it. Quite often, that ivar should be of no concern to other classes, and is an implementation detail only. As such, it has no place in the header file.

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

Implementing this ivar as a private property (a new property only declared in the Class Extension) is still useful, because of the convenient memory management boilerplate code it can abstract for you. Unfortunately, name collisions are just a fact of life in Objective C. Apple lays out some pretty clear naming conventions for you to follow (or not follow) to prevent collisions with their method names. If you're worried about collisions with the getters and setters you've invisibly created with that private property, just adopt and obsessively follow some naming convention for those private property names that you only ever use when implementing a private property. That's the best you're going to do with Objective C, but I personally think the benefits outweigh the risks.

将这个ivar实现为私有属性(仅在类扩展中声明的新属性)仍然很有用,因为它可以为您抽象内存管理样板代码。不幸的是,在Objective c中,名称冲突只是一个事实。Apple给出了一些非常清晰的命名约定,供您遵循(或不遵循),以避免与它们的方法名称发生冲突。如果您担心与您用私有属性创建的getter和setter之间的冲突,那么只需为实现私有属性时仅使用的私有属性名采用并痴迷地遵循一些命名约定。这是Objective - C的最佳效果,但我个人认为好处大于风险。