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