Наследование свойств: автоматический синтез свойств не будет синтезировать свойство

Абстрактный

Этот вопрос касается наследования свойств в сочетании с различными обращениями чтения/записи изнутри и снаружи классов, наследующих свойство друг от друга.

Подробнее

У меня есть один класс A и еще один класс B, который наследуется от A. Существует свойство someProperty, объявленное в A. Я хочу, чтобы свойство отображалось только из-за пределов этих классов и читало/записывалось изнутри.

Только с одним классом это невозможно: вы объявляете свойство в .h как readonly, и вы объявляете его снова как readwrite в .m внутри категории. Готово.

Но с двумя классами, полученными от другого, я получаю предупреждение ниже компилятора в B:

Автоматический синтез свойств не будет синтезировать свойство 'someProperty' потому что это "readwrite", но он будет синтезирован "readonly" через другое свойство

Вот код:

хиджры:

#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

Почему появляется это предупреждение и как я должен структурировать свой код, чтобы избежать его?

Ответы

Ответ 1

Вам нужно объявить свойство как чтение-запись в собственном классе (A), а затем обновить его в подклассе (B), чтобы компилятор знал, что вы хотите его использовать. Таким образом, A использует метод доступа, а B использует его. Как правило, вы не хотите, чтобы B создавал другой метод доступа, чтобы вы могли использовать @dynamic, чтобы сообщить компилятору, что суперкласс (технически, только другой класс) предоставит реализацию.

Обратите внимание, что вы также можете объявить категорию (не расширение) на A, в B.m, которая явно объявляет метод доступа (не используя свойство, просто метод), так как это то, что вы на самом деле (на самом деле вы не хотите каких-либо других вещей, которые задает свойство, и вы действительно не хотите, чтобы накладные расходы на обслуживание гарантировали, что атрибуты свойств соответствуют супер и подклассу)...