Подтвердить что ты не робот

Каков основной механизм синтеза ивара в современной среде выполнения 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? Хотя я мог бы реализовать свое собственное хранилище для данных, поддерживающих мои свойства, я бы скорее использовал механизм, который использует синтезированные аксессоры.

4b9b3361

Ответ 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"];