Objective-C如何声明类别的私有财产?
Posted
技术标签:
【中文标题】Objective-C如何声明类别的私有财产?【英文标题】:objective-C how to declare private property for category? 【发布时间】:2014-10-19 01:13:32 【问题描述】:我是 Objective-C 的新手,如果在某处重复,我深表歉意。我有一个类别(?),类似于:
在SomeClass.h
内:
@interface SomeClass (SomeCategory) <SomeDelegate>
@property (nonatomic, retain) id somePublicProperty;
@property (nonatomic, retain) id someProperty; // <-- i want to move this to "private"
@end
现在在我的SomeClass.m
中,我只有:
@implementation SomeClass (SomeCategory)
// dynamic setters/getters here for someProperty.
@end
我认为someProperty
是公开的。我如何使这个“私人”? (换句话说,我如何在语法上把它放在.m
文件中?我尝试使用
@interface SomeClass (SomeCategory)
@property (nonatomic, retain) somePrivateProperty;
@end
但它只是抱怨我有重复的类别定义。我该如何正确地做到这一点?
【问题讨论】:
【参考方案1】:在您的.h
文件中,您不应提供类别。只需使用:
@interface SomeClass : SomeBaseClass < SomeDelegate>
@property (nonatomic, retain) id somePublicProperty;
@end
在您的 .m
文件中,在 class extension 中定义您的私有属性:
@interface SomeClass ()
@property (nonatomic, retain) id somePrivateProperty;
@end
类扩展与类扩展不同,因为它允许您扩展接口以及为类添加新存储。
在一个类类别中,you can define new properties, but no storage will be allocated for it,所以你必须手动完成:
@interface SomeClass (SomeBaseCategory)
@property (nonatomic, retain) id somePrivateProperty;
@end
@implementation SomeClass
id _somePrivateProperty;
- (void)setSomePrivateProperty:(id)property
_somePrivateProperty = property;
- (id)somePrivateProperty
return _somePrivateProperty;
@end
否则你的应用会崩溃。
无论如何,请记住,鉴于 Objective-C 的动态特性,您的属性永远不会完全私有,因为您始终可以通过 objc_msgsend
向 Objective-C 对象发送消息,从而设置或读取属性值。
编辑:
如果您没有类实现的源代码,则无法定义类扩展(根据上面链接的源代码)。
在这种情况下,you could use object association to define properties。
【讨论】:
这不会使属性私有化。如果你想要一个私有属性,m 文件中的一个类别是要走的路 嗯...所以在我的代码中,SomeClass
是UIWindow
。每当我尝试按照您的建议进行操作时,我都会收到“UIWindow
类的重复接口定义”。我该如何避免这种情况?
您无法为没有源代码的类创建类扩展。我链接的文档中也说明了这一点。检查我的编辑以获取替代方法。
啊。说得通。谢谢+1【参考方案2】:
只需在 .m 文件中的实现块之外添加类别定义
像这样:
@interface MyClass (MyCategory)
@property (assign) BOOL myPrivateProperty;
@end
@implementation MyClass
...
@end
【讨论】:
塞尔吉奥,你是对的。我进行了编辑,使其成为一个类别。看起来大卫只是想要一个私有属性......所以它是类扩展还是命名类别并不重要,只要它在 m 文件中 我已经尝试过了,但我收到警告:“接口SomeClass
上的类别SomeCategory
的重复定义”。我该如何避免这种情况?
@DavidT。只需使用不同的类别名称——例如SomeCategoryUnpublished
。无论如何,这些名称不用于其他任何用途。
这不是类扩展。它是一个类别;类扩展名是@interface MyClass ()
。【参考方案3】:
类别最适合用于向您不拥有且无法更改的代码添加功能。通过类别添加属性并非不可能,但要困难得多。
类扩展最适合用于保留对象所需的属性,但不打算公开。
如果您确实需要向该对象添加属性,则可以使用 Objective-C 运行时的关联对象
有一篇关于何时/如何使用它们的精彩文章here
【讨论】:
以上是关于Objective-C如何声明类别的私有财产?的主要内容,如果未能解决你的问题,请参考以下文章