错误:可写原子属性无法将合成的 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 配对的主要内容,如果未能解决你的问题,请参考以下文章