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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With