我最近尝试编译一个较旧的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。这是唯一的方法吗?
答案 0 :(得分:217)
我遇到了同样的问题,在做了一些研究之后,这是我对这个问题的结论:
编译器会警告您声明为原子的@property
(即省略nonatomic
关键字),但是您提供了如何同步对该属性的访问的不完整实现。
使警告消失:
如果您声明@property
是原子的,请执行以下操作之一:
@dynamic
或; @synthesize
并保留合成的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方法的冒号。
编辑: 我不太确定Objective-C属性的新变化(它们现在更加智能化)如何改变这个问题的答案。也许它应该都被标记为过时。
答案 3 :(得分:0)
对于不是出于OP所述原因而出现此错误的其他人,您可能与我有相同的问题:
您有一个与-()方法同名的@property。
类似这样的东西:
std::numeric_limits<int>::min();
std::numeric_limits<int>::max();