iOS автоматически @synthesize без создания ивара

Если у меня есть @property который я не хотел поддерживать с помощью ivar Я просто опустил @synthesize и имел ручные геттеры, которые возвращали вычисленное значение.

Однако теперь, начиная с Xcode 4.4, если я не укажу @synthesize Компилятор do автоматически сгенерирует его. Означает ли это, что это также будет генерировать ivar даже я не нуждаюсь / не использую это?

Я мог в конечном итоге заставить не автоматически синтезировать с помощью dynamic, Однако это было бы неправильно, так как @dynamic предполагается использовать для отключения предупреждений, если геттер и сеттер реализованы где-то еще или во время выполнения.

3 ответа

Решение

Работая с этим, я заметил следующее поведение.

  1. Если у вас есть свойство readwrite, не имеют @synthesize, иметь геттер и не иметь сеттер, то он будет генерировать iVar.
  2. Если у вас есть свойство readwrite, не имеют @synthesize, не иметь getter, а есть setter, тогда он сгенерирует iVar.
  3. Если у вас есть свойство readwrite, не имеют @synthesize и иметь и геттер и сеттер, тогда он не будет генерировать iVar.
  4. Если у вас есть свойство только для чтения, не иметь @synthesize и не имеет геттер, то он будет генерировать iVar.
  5. Если у вас есть свойство только для чтения, не иметь @synthesize и получить геттер, то он не будет генерировать iVar.

Исходя из этого, я думаю, что общее правило таково, что если у вас нет @synthesizeи иметь все методы, необходимые для полной реализации свойства, тогда оно считается динамическим и не генерирует iVar.

В любом случае, если вы хотите убедиться, что iVar не генерируется, объявите его как @dynamic,


Разъяснение по @dynamic

Из объявленных свойств в языке программирования Objective-C:

Вы используете ключевое слово @dynamic, чтобы сообщить компилятору, что вы будете выполнять контракт API, подразумеваемый свойством, либо предоставляя реализации методов напрямую, либо во время выполнения с использованием других механизмов, таких как динамическая загрузка кода или динамическое разрешение методов.

Для меня это выглядит так, что все в порядке, чтобы пометить свойство как @dynamic, даже если вы непосредственно реализуете метод получения и установки.

Если вы пометите свойство как только для чтения и самостоятельно внедрите метод получения, похоже, что iVar не будет создан.

Объявление интерфейса:

@property (nonatomic, readonly) BOOL myBoolProp;

Impementation:

- (BOOL)myBoolProp {
    return true;
}

Пробую это:

- (void)viewDidLoad {
    [super viewDidLoad];
    _myBoolProp = true;
}

сгенерирует ошибку: использование необъявленного идентификатора '_myBoolProp'

Удаление пользовательского метода get также удаляет ошибку, которая демонстрирует, что iVar теперь сгенерирован.

Да - iVars все еще генерируются clang (не XCode, как это IDE, Clang является компилятором, который действительно имеет значение).

Если вы действительно не хотите iVars, и не хотите реализации, есть несколько архаичный @dynamic ключевое слово, которое будет делать то, что вы хотите, или вы можете указать свойство в протоколе, что не делает его автоматически синтезированным:

// .h
@property (nonatomic, retain) NSObject *someProp;

//.m
@dynamic someProp; // no iVars generated

// other solution
@protocol MyObjectProtcol<NSObject>

@property (nonatomic, retain) NSObject *someProp;

@end

// now, when you implement the MyObjectProtocol protocol, the property won't auto-synthesize.
Другие вопросы по тегам