Цель C: Почему мы объявляем ivars в области .h, если @property, кажется, делает это автоматически? - PullRequest
15 голосов
/ 05 апреля 2011

При реализации интерфейса, как представляется, распространенным методом в учебниках и литературе является объявление ивара, а затем установка @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 ]

15 голосов
/ 05 апреля 2011

Раньше было необходимо.Существуют две разные версии среды выполнения Objective C: 32-разрядная "устаревшая" среда выполнения (старая) и 32/64-разрядная среда (новая 32-разрядная среда используется только на устройствах iOS и длясимулятор iOS).

Я думаю, что единственное место, где это все еще необходимо, - это когда вы запускаете приложение в 32-битном режиме (10.5 или 10.6).Повсюду (64-битный Leopard, 64-битный Snow Leopard, Lion, iOS) использует более новую среду выполнения с «автоматическим синтезом ивара», и полученные ивары называются «синтезированными иварами».

2 голосов
/ 05 апреля 2011

Некоторые платформы поддерживают синтезированные переменные экземпляра, некоторые нет. Явное объявление переменных экземпляра делает ваш код допустимым в большем количестве мест, и это было совершенно необходимо до самого недавнего времени, поэтому люди все еще делают это. Через несколько лет они, вероятно, больше не будут.

1 голос
/ 19 октября 2013

Используя современные версии 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, но они не нужны при использовании современных инструментов.

0 голосов
/ 05 апреля 2011

@property реализует только методы доступа, сама переменная экземпляра должна существовать.Попробуйте игнорировать ivars, и он потерпит неудачу во время выполнения, если не во время компиляции.

...