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


128

我最近尝试编译一个较旧的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属性中发生吗?如果是原子属性,则最好使吸气剂/设定剂对保持锁定策略同步。如果一个部分是合成的而另一部分是自定义代码,则这很难。
Nikolai Ruhe

如果我使该属性为非原子的,它肯定会消失。有趣。我什至没有考虑过同步问题。
e.James 2010年

我访问了该主题,以找到解决该确切问题的方法。我真的不想自己写一个getter和setter。哦,好…
Constantino Tsarouhas 2011年

默认情况下,每个属性都是原子的,我们需要明确地使它们成为非原子的。原子属性是线程安全的,因此我们无法为其实现setter和getter,因为它将更改其线程安全功能。希望您能得到出现此错误的原因。
Mohd Haider 2015年

Answers:


218

我遇到了同样的问题,经过一些研究,这是我对这个问题的结论:

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

要使该警告消失:

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

  • 使用@dynamic
  • 使用@synthesize并保留合成的二传手和吸气剂,或
  • 提供手动执行两者的设定器和吸气剂(不使用上述指令中的一个)。

如果声明@propertywith,(nonatomic)则可以混合使用getter和setter的手动和综合实现。

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

从LLVM 4.0开始,CLang为声明的not属性提供了自动综合功能@dynamic。默认情况下,即使您没有使用@synthesize,编译器也会为您提供getter和setter方法。然而,对于原子性规则仍然是相同的:要么让编译器提供两个 getter和二传手,或实现他们两个自己!


谢谢!“用(非原子的)声明@属性”
Nianliang

14

您还需要实现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;
}

12

从搜索“目标C自定义属性”获得的其他热门匹配中,此问题未使用“ setter =“或“ getter =”的信息进行更新。

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

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

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

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

参考Apple文档

编辑:我不太确定对Objective-C属性的新更改(现在它们更加智能)如何更改此问题的答案。也许所有这些都应标记为过时。


我发现设置setter方法实际上并没有消除警告。例如->“ @property(assign,setter = setDelegate :) id委托;” 在这种情况下,我所能做的就是添加我自己的getter或添加nonatomic属性,我不确定是否应该这样做,因为我将自己设置为“ atomically”,因此拥有nonatomic属性并不重要,所以我了解。
大卫·范·杜格特伦

有趣,大卫。这是Objective-C的什么“版本”(我想说XCode-version会更有用)?我不确定最近对Objective-C所做的更改(特别是iOS 6)会对此产生什么影响。
Matias Forbord 2012年

0

对于并非出于OP所述原因而出现此错误的其他人,您可能与我有相同的问题:

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

像这样:

@property UIView *mainView;

-(UIView *)mainView;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.