Цель C: Почему мы объявляем ivars в области.h, если кажется, что @property делает это автоматически?
При реализации интерфейса кажется, что общий метод в учебниках и литературе заключается в том, чтобы объявить ivar, а затем установить @property
затем @synthesize
,
@interface MyClass : NSObject {
NSString *myString;
}
@property (nonatomic, retain) NSString *myString;
@end
Однако, опуская явное объявление и просто помещая @property имеет тот же эффект.
@interface MyClass: NSObject {
}
@property (nonatomic, retain) NSString *myString;
@end
Так почему же большинство людей используют @property
а явное объявление? Разве это не плохо?
4 ответа
Раньше было необходимо. Существует две разные версии среды выполнения Objective C: 32-разрядная "старая" среда выполнения (старая) и 32/64-разрядная среда (новая 32-разрядная среда используется только на устройствах iOS и для симулятор iOS).
Я думаю, что единственное место, где это все еще необходимо, - это когда вы запускаете приложение в 32-битном режиме (10.5 или 10.6). Повсюду (64-битный Leopard, 64-битный Snow Leopard, Lion, iOS) использует более новую среду выполнения, которая имеет "автоматический синтез ивара", и получающиеся в результате ивары называются "синтезированными иварами".
Некоторые платформы поддерживают синтезированные переменные экземпляра, некоторые нет. Явное объявление переменных экземпляра делает ваш код допустимым в большем количестве мест, и это было совершенно необходимо до самого недавнего времени, поэтому люди все еще делают это. Через несколько лет они, вероятно, больше не будут.
Используя современные версии Xcode (что-то около 4.2 или более поздней), нет причин объявлять iVar в вашем заголовке, НИКОГДА. Все общедоступное должно быть объявлено как собственность.
Многие забывают, что объекты Objective C на самом деле являются указателями на структуры C. Таким образом, любой iVar, который объявлен в вашем заголовке, может быть доступен напрямую, передавая ваши геттеры и сеттеры, используя myObject->myPublicIVar
, Особенно в коде не-ARC, это чрезвычайно опасно. @private
Директива запрещает использование ->
оператор для доступа к iVars, но все еще загромождает файл заголовка. Там нет смысла в @private
когда есть лучшие способы.
Все частное должно быть объявлено в вашем файле.m. Часто для этого требуется расширение класса, например:
// The .h file
@interface Foo : NSObject
@property (nonatomic, strong) NSString *myPublicString;
@end
// The .m file
@interface Foo ()
@property (nonatomic, strong) NSString *myPrivateString;
@end
@implementation Foo {
NSString *myPrivateIVar;
}
// Xcode 4.5 or later will not require these @synthesize
@synthesize myPublicString = _myPublicString;
@synthesize myPrivateString = _myPrivateString;
@end
Такая реализация обеспечивает открытое свойство, поддерживаемое iVar, частное свойство, поддерживаемое iVar, и частный независимый iVar. Я включил директивы @synthesize, но они не нужны при использовании современных инструментов.
@Property реализует только методы доступа, сама переменная экземпляра должна существовать. Попробуйте игнорировать ivars, и он потерпит неудачу во время выполнения, если не во время компиляции.