Error: 可写原子属性不能将合成的 setter/getter 与用户定义的 setter/getter 配对

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

35821 次浏览

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

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

为了消除这个警告:

如果将 @property声明为原子,请执行下列操作之一:

  • 使用 @dynamic或;
  • 使用 @synthesize并保留合成的二聚体和吸气剂或;
  • 提供一个手动实现 都有的 setter 和 getter (不使用上述指令之一)。

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

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

在 LLVM 4.0中,CLang 为声明的属性(不是 @dynamic)提供了自动合成。默认情况下,即使省略了 @synthesize,编译器也会为您提供 getter 和 setter 方法。但是,原子属性的规则仍然是相同的: 要么让编译器提供 都有 getter 和 setter,要么自己实现它们 都有

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

那么,为了提供更多关于这个问题的信息:

您可以通过编写代码将您自己的方法提供给@property 调用

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

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

参考资料 苹果文档

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

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

对于其他不是因为 OP 描述的原因而得到这个错误的人来说,你可能和我有同样的问题:

您有一个与 a-()方法同名的@属性。

就像这样:

@property UIView *mainView;


-(UIView *)mainView;