Цель 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
и явное объявление? Неплохо ли это?
Ответы
Ответ 1
Это было необходимо. Существуют две версии версии Objective-C: 32-разрядная "устаревшая" среда исполнения (старая) и 32/64-разрядная среда выполнения (новая 32-разрядная среда выполнения используется только на устройствах iOS и для iOS-симулятор).
Я думаю, что единственное место, которое все еще необходимо, - это когда вы запускаете приложение в 32-битном режиме (10.5 или 10.6). В другом месте (64-битный Leopard, 64-бит Snow Leopard, Lion, iOS) использует более новую среду исполнения, которая имеет "автоматический синтез ivar", а полученные ivars называются "синтезированными иварами".
Ответ 2
Некоторые платформы поддерживают синтезированные переменные экземпляра, некоторые - нет. Явное объявление переменных экземпляра делает ваш код действительным в большем количестве мест, и до недавнего времени он был абсолютно необходим, поэтому люди все еще это делают. Через несколько лет они, вероятно, больше не будут.
Ответ 3
Используя современные версии Xcode (что-то около 4.2 или новее), нет никаких оснований объявлять iVar в заголовке EVER. Любое общедоступное должно быть объявлено как собственность.
Многие забывают, что объекты 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, но они не нужны с использованием современных инструментов.
Ответ 4
@property реализует только методы доступа, сама переменная экземпляра должна существовать. Попробуйте игнорировать ivars, и он не будет работать во время выполнения, если не во время компиляции.