IOS автоматически @synthesize без создания ivar
Если у меня есть @property
, который я не хотел поддерживать с помощью ivar
, я просто опустил @synthesize
и имел ручные getters, которые возвращали вычисленное значение.
Однако теперь, поскольку Xcode 4.4, если я не укажу @synthesize
, компилятор автоматически сгенерирует его. Означает ли это, что он также будет генерировать ivar
, даже если мне это не нужно/не использовать?
В итоге я мог бы не автосинхронизировать, используя dynamic
. Однако это было бы неправильно, поскольку @dynamic
предполагается использовать для отключения предупреждений, если getter и setter реализованы где-то еще или во время выполнения.
Ответы
Ответ 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.