【问题标题】:objective-C how to declare private property for category?Objective-C如何声明类别的私有财产?
【发布时间】: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

但它只是抱怨我有重复的类别定义。我该如何正确地做到这一点?

【问题讨论】:

    标签: ios objective-c private objective-c-category


    【解决方案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 文件中的一个类别是要走的路
    • 嗯...所以在我的代码中,SomeClassUIWindow。每当我尝试按照您的建议进行操作时,我都会收到“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

    【讨论】:

      猜你喜欢
      • 2014-12-10
      • 2018-02-19
      • 2013-04-27
      • 2018-05-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2011-11-09
      • 2012-01-24
      相关资源
      最近更新 更多