Цель 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, и он потерпит неудачу во время выполнения, если не во время компиляции.

Другие вопросы по тегам