Существует класс, который выглядит следующим образом (я сокращаю импорт для краткости):
Base.h:
@interface Base : NSObject
@property (strong, readonly) NSString *something;
- (id)initWithSomething:(NSString *)something;
@end
Base.m:
@implementation Base
- (id)initWithSomething:(NSString *)something {
self = [super init];
if (self) _something = something;
return self;
}
@end
Как вы видите, свойство "что-то" доступно только для чтения. Теперь я хочу создать подкласс, который переопределяет это свойство для записи:
Sub.h:
@interface Sub : Base
@property (strong) NSString *something;
@end
Sub.m:
@implementation Sub
@end
И код:
main.c:
int main(int argc, const char * argv[]) {
@autoreleasepool {
Sub *o = [Sub new];
o.something = @"foo";
NSLog(@"%@", o.something);
}
return 0;
}
Этот код приводит к:
2013-09-07 13:58:36.970 ClilTest[3094:303] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[Sub setSomething:]: unrecognized
selector sent to instance 0x100109ff0'
Почему? Почему он не находит setSelector?
Когда я делаю это в подклассе, вместо этого:
Sub.m:
@implementation Sub
@synthesize something = _something;
@end
все работает. Означает ли это, что свойство подкласса не синтезируется по умолчанию, хотя оно определено как @property
в @interface
? Компиляция каким-то образом "видит" автоматически созданный геттер с базы и не генерирует сеттер? И почему, я думаю, сеттер должен быть сгенерирован, поскольку он еще не существует. Я использую Xcode 4.6.2, а проект - Cli Tool (тип Foundation), но то же самое происходит в моем фактическом проекте, который является приложением для iPhone.
Фон: у меня есть тяжелый объект (экземпляр Base), который требует подключения Bluetooth к некоторому оборудованию, и я должен создать контроллер вида для некоторых функций. Для легкого тестирования я не хочу подключаться к BT (на самом деле, мне нужно было бы физическое устройство и проверить код на нем), я бы хотел проверить его на симуляторе.
Я пришел к выводу, что я просто создаю подкласс (Sub), который заглушает несколько методов/свойств и использует его вместо этого, и когда код готов, я просто удалю код для подкласса, заменим его экземпляр на правильный, протестировать устройство, зафиксировать и нажать. Он действительно работает отлично, за исключением странной вещи с @property
выше.
Может ли кто-нибудь сказать мне, что происходит с переопределением свойства?