Документ Apple, цитируемый позже, похоже, указывает на то, что это допустимо, хотя я признаю, что у меня никогда не было причин делать это в подклассе до сих пор.
У меня есть базовый класс с общедоступным свойством readwrite и подклассом, в котором я повторно объявляю свойство только для чтения.У подкласса также есть расширение класса, которое снова объявляет свойство как readwrite, чтобы получить общий шаблон Objective-C "public readonly, private readwrite".Однако я получаю следующее предупреждение компилятора:
warning: Semantic Issue: Attribute 'readonly' of property 'foo' restricts attribute 'readwrite' of property inherited from 'Base'
Я использую Xcode 4.1 build 4B110 с LLVM 2.1 (хотя LLVM GCC4.2 и GCC4.2 выдают одно и то же предупреждение) на 10.7.
Вот урезанный пример с предупреждением компилятора:
#import <Foundation/Foundation.h>
@interface Base : NSObject
@property (nonatomic, readwrite) BOOL foo;
@end
@implementation Base
@dynamic foo;
@end
// Subclass
@interface Sub : Base
@property (nonatomic, readonly) BOOL foo;
@end
// Class extension
@interface Sub ()
@property (nonatomic, readwrite) BOOL foo;
@end
@implementation Sub
@dynamic foo; // it warns with @synthesize as well
@end
Вот соответствующий отрывок из Apple Язык программирования Objective-C :
Переопределение свойства
Вы можете повторно объявить свойство в подклассе, но (за исключением чтения только для чтения и записи) вы должны полностью повторить его атрибуты в подклассах.То же самое относится и к свойству, объявленному в категории или протоколе - хотя свойство может быть повторно объявлено в категории или протоколе, атрибуты свойства должны повторяться полностью.
Если вы объявите свойство в одном классе какТолько для чтения вы можете переопределить его как readwrite в расширении класса (см. «Расширения»), в протоколе или в подклассе (см. «Подклассы со свойствами»).В случае переопределения расширения класса тот факт, что свойство было объявлено перед любым оператором @synthesize, вызывает синтезатор сеттера.Возможность повторного объявления свойства «только для чтения» как «чтение / запись» включает два общих шаблона реализации: изменяемый подкласс неизменяемого класса (все примеры - NSString, NSArray и NSDictionary) и свойство, имеющее общедоступный API, доступный только для чтения, ночастная реализация readwrite внутри класса.В следующем примере показано использование расширения класса для предоставления свойства, которое объявлено в общедоступном заголовке как доступное только для чтения, но переобъявлено в частном порядке как чтение / запись.
Я переобозначаю общедоступные свойства readonly в расширениях классавсе время, но я думаю, у меня никогда не было причин делать это подклассом.Однако, если я не читаю это неправильно, параграфы выше, кажется, указывают, что это кошерно.Может кто-нибудь объяснить мне и / или примирить очевидный конфликт между документами и компилятором?
Почему я хочу это сделать?Моя ситуация в реальном мире, конечно, более сложная.Я могу внести изменения в конструкцию, чтобы обойти это, если необходимо, но это выглядело как альтернатива с наименьшим трением (необходимость делать это вообще обусловлена другими изменениями).