Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

property inheritance: Auto property synthesis will not synthesize property

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?

like image 594
Daniel S. Avatar asked Jul 04 '14 09:07

Daniel S.


1 Answers

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)...

like image 170
Wain Avatar answered Oct 21 '22 23:10

Wain