Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does this objective-c property synthesis warning mean?

Since upgrading to Xcode 5.1, I'm starting to see the following warning in some code my project uses. I'm trying to figure out what it means.

Warning: Auto property synthesis will not synthesize property 'responseHeader' because it is 'readwrite' but it will be synthesized 'readonly' via another property

The code where it's occurring, in the .m file:

@interface S3Response ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end

The previous declaration of the property, in the .h file:

@property (nonatomic, readonly) NSDictionary *responseHeader;

There is no @synthesize statement for that property, nor are responseHeader or setResponseHeader defined as methods. There is however an explicit definition of an ivar named responseHeader.

Seems pretty straightforward to me: property is declared as read-only for users of the class, but read-write locally so the class can set it.

What does this warning mean, and what should I do about it?

like image 776
dpassage Avatar asked Mar 16 '14 21:03

dpassage


1 Answers

That code seems to be from the AWS SDK for iOS, and S3Response is a subclass of AmazonServiceResponse.

The public AmazonServiceResponse interface defines a read-only property

@interface AmazonServiceResponse:NSObject
// ...
@property (nonatomic, readonly) NSDictionary *responseHeader;
@end

which is redefined as read-write in a class extension in the implementation file:

@interface AmazonServiceResponse ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end

Now the subclass S3Response also wants read-write access to this property, and therefore also defines in the class extension of its implementation file:

@interface S3Response ()
@property (nonatomic, readwrite, retain) NSDictionary *responseHeader;
@end

The compiler complains because – when compiling "S3Response.m" – it does not know that a setter for the property exists in the superclass (it does not read the implementation file of the superclass at that point). Also the compiler cannot simply synthesize a setter in the subclass, because it cannot not know that the property is backed-up by an instance variable in the superclass.

But you know that a setter will be generated, so you can remove the warning by adding a @dynamic declaration to the subclass implementation:

@implementation S3Response
@dynamic responseHeader;
...

@dynamic is a "promise" to the compiler that all necessary accessor methods will be available at runtime.

like image 142
Martin R Avatar answered Oct 24 '22 05:10

Martin R