В ранние дни Obj-C и до сих пор вы объявили переменные в заголовочном файле вашего класса следующим образом:
@interface MySubclass : NSObject {
int varName;
}
Тогда вам придется вручную создавать методы setter и getter для доступа к переменной за пределами вашего класса. Чтобы помочь справиться с управлением памятью (полезно для объектов), Apple представила свойства в Obj-C 2.0, и это позволило вам определить методы доступа для данной переменной. Вы могли бы сказать, что переменная будет иметь определенные атрибуты (такие как сохранение или копирование значения, наличие альтернативного имени установщика или получателя и т. Д.), И вы определили это как:
@property (someAttributes) int varName;
тогда в вашей @implementation вы можете @synthesize эти свойства с заданными атрибутами, и компилятор сгенерирует методы setter и getter для вашей переменной.
@synthesize varName; // Generates -setVarName: and -varName for you
Теперь идея состоит в том, что вы можете отказаться от реализации переменных экземпляра в разделе {} и просто объявить свойство и синтез. Что мы получим, если просто скажем
@property (nonatomic) double topSpeed;
@synthesize topSpeed;
является установщиком и получателем с именем setTopSpeed: и topSpeed с переменной экземпляра topSpeed (созданной компилятором) для хранения значения. Идея @synthesize topSpeed = _topSpeed;
состоит в том, что имя переменной экземпляра будет _topSpeed
, а имена методов доступа по-прежнему будут -setTopSpeed:
и -topSpeed
. Это помогает для читабельности кода, потому что может возникнуть путаница между тем, когда вы говорите self.topSpeed или topSpeed в вашем коде (первый вызывает метод доступа, а второй - ивар). _TopSpeed отличается от обычных переменных, а также делает это явным, когда вы вызываете self.topSpeed (метод доступа) против _topSpeed (ivar). Apple также переходит к этому синтаксису подчеркивания, так что не думайте, что он вымирает, потому что это совсем наоборот. Обновление: (см. Комментарий Томми)
Это также помогает при конфликтах имен переменных. Если бы вам пришлось реализовать setTopSpeed: вы бы выглядели примерно так:
- (void)setTopSpeed:(double)topSpeed {
_topSpeed = topSpeed; // _topSpeed makes it obvious it's an ivar
}