Каков основной механизм синтеза ивара в современной среде выполнения Objective C?

StackOverflow https://stackoverflow.com/questions/275034

  •  07-07-2019
  •  | 
  •  

Вопрос

Одной из особенностей современной (64-битной OS X и iPhone OS) среды выполнения Objective C является возможность для свойств динамически синтезировать ивары без явного объявления их в классе:

@interface MyClass : NSObject {
//  NSString *name; unnecessary on modern runtimes
}

@property (retain) NSStrng *name;

@end

@implementation MyClass

@synthesize name;

@end

В большей части моего кода я использую пользовательские реализации геттеров для инициализации свойств:

- (NSString *) name {
  if (!name) {
    name = @"Louis";
  }

  return name;
}

Вышеприведенное несовместимо с синтезированными иварами, так как ему необходим доступ к ивару, который не объявлен в заголовке. По разным причинам я хотел бы обновить ряд моих личных фреймворков для использования синтезированных иваров при построении на современных средах исполнения. Для достижения этой цели необходимо изменить приведенный выше код для работы с синтезированными иварами.

Хотя в документации Objective C 2.0 говорится, что синтезированные средства доступа в современной среде выполнения будут синтезировать ivar при первом использовании. Он не указывает, какой механизм низкого уровня используется для этого. Это сделано с помощью class_getInstanceVariable (), ослаблены ли ограничения на class_addIvar (), это недокументированная функция в целевой среде выполнения C 2.0? Хотя я мог бы реализовать свое собственное стороннее хранилище для данных, поддерживающих мои свойства, я бы предпочел использовать механизм, который используют синтезированные методы доступа.

Это было полезно?

Решение

Я пошел и снова посмотрел документацию, и я думаю, что вы неправильно ее прочитали. Синтезированные ивары создаются во время компиляции, а не во время выполнения.

Согласно документации Objective-C 2.0

  

Существуют различия в поведении, которые зависят от времени выполнения (см. также & # 8220; Различия во время выполнения & # 8221;):

     

Для устаревших сред выполнения переменные экземпляра уже должны быть объявлены в блоке @interface. Если переменная экземпляра с тем же именем и совместимым типом, что и у свойства, существует, она используется & # 8212; в противном случае вы получите ошибку компилятора.

     

Для современных сред выполнения переменные экземпляра синтезируются по мере необходимости. Если переменная экземпляра с таким именем уже существует, она используется.

Итак, все, что вам нужно сделать, это объявить переменную экземпляра, которая вам нужна, и один и тот же код будет работать в обеих средах выполнения ...

Другие советы

То, что вы ищете, это @synthesized name, например:

@synthesize name = _name;

...

- (NSString *) name {
    if (!name) {
        _name = @"Louis";
    }

    return _name;
}

Вы добавляете свойства во время выполнения с помощью Протокол NSKeyValueCoding .

[myObject setValue:@"whatever" forKey:@"foo"];
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top