Каков основной механизм синтеза ивара в современной среде выполнения Objective C
Одной из особенностей современной (64-разрядной OS X и iPhone OS) Objective C является способность свойств динамически синтезировать ivars без явного объявления их в классе:
@interface MyClass : NSObject {
// NSString *name; unnecessary on modern runtimes
}
@property (retain) NSStrng *name;
@end
@implementation MyClass
@synthesize name;
@end
В довольно небольшом моем коде я использую пользовательские реализации getter для инициализации свойств:
- (NSString *) name {
if (!name) {
name = @"Louis";
}
return name;
}
Вышеупомянутое несовместимо с синтезированными ivars, поскольку ему необходимо получить доступ к ivar, который не объявлен в заголовке. По разным причинам я хотел бы обновить ряд моих персональных фреймворков для использования синтезированных иваров, когда они построены на современных средах выполнения, вышеуказанный код необходимо модифицировать для работы с синтезированными иварами для достижения этой цели.
В то время как документация Objective C 2.0 гласит, что синтезированные аксессоры в современной среде выполнения будут синтезировать ivar при первом использовании. Он не указывает, какой механизм низкого уровня используется для этого. Это делается классом_getInstanceVariable(), являются ли ограничения на class_addIvar() ослабленными, является ли это недокументированной функцией int Object Object C 2.0 runtime? Хотя я мог бы реализовать свое собственное хранилище для данных, поддерживающих мои свойства, я бы скорее использовал механизм, который использует синтезированные аксессоры.
Ответы
Ответ 1
Я пошел и снова посмотрел документацию, и я думаю, что вы неправильно ее понимаете. Синтезированные ивары создаются во время компиляции, а не во время выполнения.
В соответствии с Objective-C 2.0 документация:
Существуют различия в поведении, зависящем от времени выполнения (см. также "Различия времени выполнения" ):
Для устаревшей среды выполнения переменные экземпляра уже должны быть объявлены в блоке @interface. Если переменная экземпляра с тем же именем и совместимым типом, что и свойство, существует, используется, иначе вы получите ошибку компилятора.
Для современных сред выполнения переменные экземпляра синтезируются по мере необходимости. Если переменная экземпляра с тем же именем уже существует, она используется.
Итак, все, что вам нужно сделать, это объявить переменную экземпляра, в которой вы нуждаетесь, и тот же код будет работать в обоих режимах времени...
Ответ 2
То, что вы ищете, это имя @synthesized, например:
@synthesize name = _name;
...
- (NSString *) name {
if (!name) {
_name = @"Louis";
}
return _name;
}
Ответ 3
Вы добавляете свойства во время выполнения с помощью протокола NSKeyValueCoding.
[myObject setValue:@"whatever" forKey:@"foo"];