Наследование свойств: автоматический синтез свойств не будет синтезировать свойство
Абстрактный
Этот вопрос касается наследования свойств в сочетании с различными обращениями чтения/записи изнутри и снаружи классов, наследующих свойство друг от друга.
Подробнее
У меня есть один класс 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, которая явно объявляет метод доступа (не используя свойство, просто метод), так как это то, что вы на самом деле (на самом деле вы не хотите каких-либо других вещей, которые задает свойство, и вы действительно не хотите, чтобы накладные расходы на обслуживание гарантировали, что атрибуты свойств соответствуют супер и подклассу)...