I recently tried to compile an older Xcode project (which used to compile just fine), and now I’m seeing a lot of errors of this form:
error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter
The code pattern which causes these errors always looks like this:
// Interface:
@property (retain) NSObject * someProperty;
// Implementation:
@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
//..
}
I can see why the error is being generated. I tell the compiler to synthesize my property accessors (both getter and setter), and then immediately afterward I override the setter manually. That code has always smelled a little off.
So, what is the proper way to do this? If I use @dynamic instead of @synthesize, I will have to write the getter as well. Is that the only way?
I had the same problem and after doing a bit of research, here is my conclusion about this issue:
The compiler warns you about a
@propertythat you declared as atomic (i.e. by omitting thenonatomickeyword), yet you provide an incomplete implementation of how to synchronize access to that property.To make that warning disappear:
If you declare a
@propertyto be atomic then do one of the following:@dynamicor;@synthesizeand keep the synthesized setter and getter or;If you declare the
@propertywith(nonatomic)then you can mix manual and synthesized implementations of getters and setters.Update: A Note on Property Auto-Synthesis
As of LLVM 4.0, CLang provides auto-synthesis for declared properties that are not
@dynamic. By default, even if you leave out the@synthesize, the compiler will provide getter and setter methods for you. However, the rule for atomic properties is still the same: Either let the compiler provide both the getter and the setter, OR implement them both yourself!