Подтвердить что ты не робот

Objective-C свойство и синтезирующая логика

Каково фактическое имя переменной экземпляра, скажем, topSpeed, как из лекций Стэнфордского университета о развитии Objective-C и iOS?

Вот код:

@property (nonatomic) double topSpeed;

Глядя на этот код, я думаю, что я определил переменную topSpeed ​​в классе. Я не могу понять, почему он автоматически объявит метод getter с именем, аналогичным имени переменной - topSpeed?

Другой вопрос, когда мы используем

@synthesize topSpeed = _topSpeed

И если мы посмотрим, что будет генерировать @synthesize:

- (double) setTopSpeed:(double)speed
{
   _topSpeed = speed;
}


- (double) topSpeed
{
   return _topSpeed;
}

Что такое _topSpeed ​​здесь и что такое topSpeed? Я объявил переменную topSpeed, а не _topSpeed. Что делать, если я не использую свойство, каким бы имя переменной было?

4b9b3361

Ответ 1

В более ранние дни 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;

- это сеттер и getter, называемый setTopSpeed: и topSpeed ​​с переменной экземпляра, называемой topSpeed ​​(созданной компилятором) для хранения значения. Идея @synthesize topSpeed = _topSpeed; заключается в том, что имя переменной экземпляра будет _topSpeed, но имена аксессуаров все равно будут -setTopSpeed: и -topSpeed. Это помогает считывать код, потому что может возникнуть путаница между тем, когда вы говорите self.topSpeed ​​или topSpeed ​​в своем коде (первый вызывает аксессуар, второй - ivar). _topSpeed ​​отличает себя от обычных переменных, а также делает его явным, когда вы вызываете self.topSpeed ​​(accessor) vs _topSpeed ​​(ivar). Apple также переходит к этому синтаксису подчеркивания, поэтому не думайте, что он исчезнет, ​​потому что это совсем наоборот. Обновление: (См. Комментарий Томми)

Он также помогает при столкновении с переменными именами. Если вам нужно было реализовать setTopSpeed: вы бы выглядели примерно так:

setTopSpeed:(double)topSpeed {
    _topSpeed = topSpeed; // _topSpeed makes it obvious it an ivar
}

Ответ 2

  • Это синтаксический синтаксис , позволяющий вводить меньшее слово.
  • В отличие от java/С++, в obj-c вы не можете получить доступ к переменной класса. Вы могли бы только вызвать методы It.
  • @synthesize topSpeed = _topSpeed означает, что вам нужна переменная с именем _topSpeed ​​и имеет аксессуры с именем topSpeed ​​и setTopSpeed.
  • @property (nonatomic) double topSpeed; не объявление чистой переменной, оно также объявит Accessors. Чистая переменная класса Foo будет выглядеть так:

    @interface Foo: NSObject { double topSpeed; }

Ответ 3

Для первого вопроса ответ - "соглашение об именах". Так что это только соглашение об именах. Если вы хотите получить доступ к переменной topSpeed, часть "получить" не имеет значения - например, [car topSpeed] легче читать, чем [car getTopSpeed]. Что касается второго вопроса, я не уверен, но я считаю, что вы получаете доступ к свойству topSpeed через переменную _topSpeed.