17

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?

dpassage
  • 5,423
  • 3
  • 25
  • 53

2 Answers2

23

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Sure enough, this fixed the issue. Plus points for figuring out exactly what code I was talking about :) Still, that's a pretty crummy warning message. – dpassage Mar 17 '14 at 01:39
  • in Xcode6, it does NOT work, you need to follow this: http://stackoverflow.com/questions/22384364/auto-property-synthesis-property-and-inheritance – LiangWang Jul 25 '14 at 10:38
  • @Jacky: Can you clarify your statement? I just verified with Xcode 6 beta 4 and the AWS SDK for iOS v1.7.1 that my suggested solution still fixes the compiler warning. Adding `@dynamic ...` is also suggested in the answer to the question that you linked to. - Thank you for your feedback! – Martin R Jul 25 '14 at 10:55
-1

The problem here is as follows.

By default, if don't write ownership (weak/retain/strong/assign) explicitly, xCode will check the type automatically. So in case of NSDictionary it will be strong. Thus, in interface you will have

@property (nonatomic, readonly, strong) NSDictionary *responseHeader;

Then it will be contradict you private implementation definition

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

Compilator doesn't match strong and retain under property synthesizing though it is formally the same thing.

To cure situation you can write retain in both cases, or more correct, you should not write retain at all. It will be strong by default in both definitions.

malex
  • 9,874
  • 3
  • 56
  • 77
  • 1
    `strong` and `retain` are equivalent, so if this is true, it should be considered a bug. (Although a pedantic warning from the compiler about the mismatch would probably be appropriate.) – jscs Mar 16 '14 at 22:28
  • 1
    It is true from the ownership viewpoint. But it seems that some automatic mechanisms of ARC distinguish them for some reason. – malex Mar 16 '14 at 22:30
  • "strong" and "retain" are complete synonyms and can be mixed without causing any warning. – Martin R Mar 16 '14 at 22:52