我最近尝试编译一个较旧的 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。这是唯一的方法吗?
我遇到了同样的问题,经过一番研究后,这是我对这个问题的结论:
编译器会警告您声明为原子的
@property
(即通过省略 nonatomic
关键字),但您提供了如何同步对该属性的访问的不完整实现。
要使该警告消失:
如果您将
@property
声明为原子,则执行以下操作之一:
@dynamic
或;@synthesize
并保留合成的 setter 和 getter 或;如果您使用
@property
声明 (nonatomic)
,那么您可以混合 getter 和 setter 的手动和合成实现。
更新:属性自动合成注意事项
从 LLVM 4.0 开始,CLang 为非
@dynamic
声明的属性提供自动合成。默认情况下,即使你省略了 @synthesize
,编译器也会为你提供 getter 和 setter 方法。然而,原子属性的规则仍然是相同的:要么让编译器提供 both getter 和 setter,或者自己实现它们 both!
您还需要实现 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;
}
这个问题,以及您通过搜索“objective C custom property”获得的其他热门搜索结果,并未使用有关“setter =”或“getter =”的信息进行更新。
因此,提供有关此问题的更多信息:
您可以通过编写以下内容来使用您自己的方法提供 @property 调用
@property(setter = MySetterMethod:, getter = MyGetterMethod)
注意所提供的 setter 方法的冒号。
参考 Apple 文档
编辑: 我不太确定 Objective-C 属性的新变化(它们现在更加智能)如何改变这个问题的答案。也许应该全部标记为已过时。
对于其他不是因为OP描述的原因而收到此错误的人,您可能有与我相同的问题:
您有一个与 -() 方法同名的@property。
类似这样的:
@property UIView *mainView;
-(UIView *)mainView;