【问题标题】:Why does a declared property use both retain and readonly?为什么声明的属性同时使用保留和只读?
【发布时间】:2009-12-19 17:05:29
【问题描述】:

我注意到 Apple 的一些示例在属性上同时包含 retainreadonly 修饰符。如果在我们使用 readonly 修饰符时没有生成 setter,那么包含 retain 有什么意义?

示例:来自 AnimatedTableView 示例的@property (retain, readonly) NSString *title;

【问题讨论】:

    标签: objective-c memory-management declared-property


    【解决方案1】:

    或者,更具体地说,(只读,保留)启用这样的模式:

    Foo.h:

    @interface StuffHolder:NSObject
    @property(readonly, retain) MyStuff *stuff;
    @end
    

    Foo.m:

    @interface StuffHolder()
    @property(readwrite, retain) MyStuff *stuff;
    @end
    
    @implementation StuffHolder
    @synthesize stuff;
    @end
    

    最终结果是一个公开只读的属性,同时在实现中是读写的,并且编译器会自动合成 setter 和 getter。

    警告可能在类扩展中没有(readwrite,retain)覆盖的情况下生成——类似于statement without an effect——但这会更令人困惑而不是有益。组合中还有大量不同的边缘情况同样需要警告,但并不真正表明存在实际问题。为简单起见,决定在很大程度上接受各种模式而不会抱怨(因为它们不是正确性问题)。

    【讨论】:

    • 它被宣传为只读,但如果编译器为它生成了一个 setter,它仍然是可写的,不是吗?
    • 如果有人要编写代码来调用 setter,当然,但没有在某处声明该方法,他们会看到一个警告...
    • “Public”只读属性(在标头中声明)和“private”保留属性(在源文件中声明)不再受支持(使用 Xcode 3.2.3 - iPhone SDK 4 和 GCC 3.2)错误:综合属性 'x' 和 'y' 都声称 ivar 'z'
    • 它们肯定是受支持的。如果您发现特定模式不起作用(应该是),请提交错误! bugreport.apple.com
    【解决方案2】:

    您可以在类扩展中包含第二个私有的读写声明。所有引用的内存管理方案都需要匹配 IIRC,所以你会得到像“只读,保留”这样的愚蠢。

    【讨论】:

    • 这并不完全是愚蠢的;修饰符与@synthesize 的矩阵使得getter 的代码可以改变。试图准确地确定应该能够添加哪些修饰符与应该添加哪些#warn 会充满细节并且最终难以理解。最好简单地使用“必须相同,除了 readonly->readwrite”。
    猜你喜欢
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 2013-10-30
    • 1970-01-01
    • 2015-10-05
    • 2014-06-21
    相关资源
    最近更新 更多