错误:可写原子属性无法将合成的 setter/getter 与用户定义的 setter/getter 配对

Posted

技术标签:

【中文标题】错误:可写原子属性无法将合成的 setter/getter 与用户定义的 setter/getter 配对【英文标题】:error: writable atomic property cannot pair a synthesized setter/getter with a user defined setter/getter 【发布时间】:2011-03-14 17:16:45 【问题描述】:

我最近尝试编译一个较旧的 Xcode 项目(以前编译得很好),现在我看到了很多这种形式的错误:

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

导致这些错误的代码模式总是如下所示:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue

    //..

我知道为什么会产生错误。我告诉编译器合成我的属性访问器(getter 和 setter),然后立即手动覆盖 setter。那个代码总是有点不对劲。

那么,这样做的正确方法是什么?如果我使用@dynamic 而不是@synthesize,我也必须编写getter。这是唯一的方法吗?

【问题讨论】:

这是否只发生在atomic 属性上?在原子属性的情况下,保持 getter/setter 对在锁定策略方面同步可能是一个好主意。如果一个部分是合成的,而另一个是自定义代码,这会很困难。 如果我将属性设为非原子属性,它肯定会消失。有趣的。我什至没有考虑过同步问题。 我访问了这个主题以找到解决这个确切问题的方法。我真的不想自己写一个getter和setter。哦,好吧…… 默认情况下每个属性都是原子的,我们需要明确地使它们成为非原子的。原子属性是线程安全的,所以我们不能为它们实现 setter 和 getter,因为它会改变它的线程安全功能。我希望你能明白为什么会出现这个错误。 【参考方案1】:

我也遇到了同样的问题,经过一番研究,我对这个问题的结论如下:

编译器会警告您声明为原子的 @property(即通过省略 nonatomic 关键字),但您提供了如何同步访问该属性的不完整实现。

要使该警告消失:

如果您将 @property 声明为原子,则执行以下操作之一:

使用@dynamic 或; 使用@synthesize 并保留合成的setter 和getter 或; 提供setter 和getter 的手动实现(不使用上述指令之一)。

如果您声明 @property(nonatomic),那么您可以混合使用手动和合成的 getter 和 setter 实现。

更新:关于属性自动合成的说明

从 LLVM 4.0 开始,CLang 为声明的非 @dynamic 属性提供自动综合。默认情况下,即使您省略了@synthesize,编译器也会为您提供getter 和setter 方法。然而,原子属性的规则还是一样的:要么让编译器同时提供 getter 和 setter,要么自己实现它们both

【讨论】:

谢谢! “用(非原子)声明@property”【参考方案2】:

您还需要实现 getter。示例:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

- (void)setSomeProperty:(NSObject *)newValue

    @synchronized (self)
    
        // ...
    


- (NSObject *)someProperty

    NSObject *ret = nil;

    @synchronized (self)
    
        ret = [[someProperty retain] autorelease];
    

    return ret;

【讨论】:

【参考方案3】:

在搜索“objective C custom property”时获得的其他热门问题中,此问题未更新有关“setter =”或“getter =”的信息。

因此,提供有关此问题的更多信息:

您可以通过编写使用自己的方法提供@property 调用

    @property(setter = MySetterMethod:, getter = MyGetterMethod)

注意提供的 setter 方法的冒号。

参考Apple documentation

编辑: 我不太确定 Objective-C 属性的新变化(它们现在更加智能)如何改变这个问题的答案。也许应该全部标记为过期。

【讨论】:

我发现设置setter方法实际上并没有消除警告。例如-> "@property (assign, setter = setDelegate:) id delegate;"在这种情况下,我所能做的就是添加自己的 getter 或添加非原子属性,我不确定是否应该这样做,因为我自己“原子地”设置委托,拥有非原子属性并不重要,或者我理解。 有趣,大卫。这是什么“版本”的Objective-C(我想说XCode-version会更有帮助)?我不确定最近对 Objective-C 的更改,特别是 ios 6 的更改会对此有何影响。【参考方案4】:

对于不是因为 OP 描述的原因而出现此错误的其他人,您可能遇到与我相同的问题:

您有一个与 -() 方法同名的 @property。

类似这样的:

@property UIView *mainView;

-(UIView *)mainView;

【讨论】:

以上是关于错误:可写原子属性无法将合成的 setter/getter 与用户定义的 setter/getter 配对的主要内容,如果未能解决你的问题,请参考以下文章

三属性和点语法

奇怪的 Haskell 'stack' 错误:“无法加载 .so/.DLL”“不是可写段”

mapreduce 中的可写类

无法合成信号

第6条:理解“属性”这一概念(中)

事务的四个属性ACID