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

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

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

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

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

4b9b3361

Ответ 1

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

  • Если у вас есть свойство readwrite, не имеет @synthesize, у вас есть геттер и у меня нет сеттера, тогда он будет генерировать iVar.
  • Если у вас есть свойство readwrite, не имеет @synthesize, у вас нет получателя и есть сеттер, тогда он будет генерировать iVar.
  • Если у вас есть свойство readwrite, не имеет @synthesize и у него есть как getter, так и setter, тогда он не будет генерировать iVar.
  • Если у вас есть свойство readonly, не имеет @synthesize и не имеет getter, тогда он будет генерировать iVar.
  • Если у вас есть свойство readonly, не имеет @synthesize и у вас есть геттер, то он не будет генерировать iVar.

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

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


Уточнение в @dynamic

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

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

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

Ответ 2

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

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

@property (nonatomic, readonly) BOOL myBoolProp;

Impementation:

- (BOOL)myBoolProp {
    return true;
}

Попытка:

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

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

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

Ответ 3

Да - 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.