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

时间:2010-07-12 09:21:39

标签: objective-c xcode compiler-construction properties

我最近尝试编译一个较旧的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。这是唯一的方法吗?

4 个答案:

答案 0 :(得分:217)

我遇到了同样的问题,在做了一些研究之后,这是我对这个问题的结论:

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

使警告消失:

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

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

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

更新:关于属性自动合成的注意事项

从LLVM 4.0开始,CLang为非@dynamic的声明属性提供自动合成。默认情况下,即使您省略@synthesize,编译器也会为您提供getter和setter方法。但是,原子属性的规则仍然是相同的:让编译器提供两者 getter和setter,或者自己实现两者

答案 1 :(得分:13)

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

答案 2 :(得分:12)

这个问题,在搜索“目标C自定义属性”时获得的其他热门搜索中,并未更新有关“setter =”或“getter =”的信息。

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

您可以通过编写

来使用自己的方法提供@property调用
    @property(setter = MySetterMethod:, getter = MyGetterMethod)

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

参考Apple documentation

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

答案 3 :(得分:0)

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

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

类似这样的东西:

std::numeric_limits<int>::min();
std::numeric_limits<int>::max();