Reputation: 6650
Abstract:
This question is about inheritance of properties in combination with different read/write accesses from inside and outside of the classes inheriting the property from one another.
Details:
I have one class A
and another class B
, which inherits from A
. There is the property someProperty
declared in A
. I want the property to be readonly from outside these classes and read/write from inside.
With only one class, this is dead-simple: You declare the property in the .h
as readonly and you declare it again as readwrite in the .m inside of a category. Done.
But with the two classes, one deriving from the other, I get the below compiler warning in B
:
Auto property synthesis will not synthesize property 'someProperty' because it is 'readwrite' but it will be synthesized 'readonly' via another property
Here is the code:
A.h:
#import <Foundation/Foundation.h>
@interface A : NSObject
// This property shall be readonly from outside, but read/write from subclasses
@property (readonly) SInt32 someProperty;
@end
A.m:
#import "A.h"
@implementation A
@end
B.h:
#import <Foundation/Foundation.h>
#import "A.h"
@interface B : A
@end
B.m:
#import "B.h"
@interface B ()
// compiler warning in the following property declaration:
// /Users/.../B.m:12:41: Auto property synthesis will not synthesize property
// 'someProperty' because it is 'readwrite' but it will be synthesized
// 'readonly' via another property
@property (readwrite) SInt32 someProperty;
@end
@implementation B
@end
Why does this warning appear and how should I structure my code to avoid it?
Upvotes: 18
Views: 20105
Reputation: 119041
You need to declare the property as read-write on the owning class (A
), and then redeclare on the subclass (B
) to make the compiler aware that you want to use it there. So, A
hosts the accessor method and B
uses it. Generally you don't want B
to create another accessor method so you can use @dynamic
to tell the compiler that the superclass (technically, just another class) will provide the implementation.
Note that you can also declare a category (not extension) on A
, in B
.m which declares the accessor method explicitly (not using a property, just a method) as that is what you're actually interested in (you don't actually want any of the other things that a property specifies and you don't really want the maintenance overhead of ensuring that the property attributes match in the super and subclass)...
Upvotes: 10