Свойство Objective-C и синтезировать логику - PullRequest
14 голосов
/ 03 марта 2012

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

Вот код:

@property (nonatomic) double topSpeed;

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

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

@synthesize topSpeed = _topSpeed

И если мы посмотримпри чем @synthesize сгенерирует:

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


- (double) topSpeed
{
   return _topSpeed;
}

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

Ответы [ 3 ]

39 голосов
/ 03 марта 2012

В ранние дни 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
}
3 голосов
/ 03 марта 2012
  1. Это синтаксический сахар , позволяет вводить меньше слов.
  2. В отличие от java / c ++, в obj-c вы не можете получить доступ к переменнойкласса.Вы можете вызывать только Его методы.
  3. @synthesize topSpeed = _topSpeed означает, что вам нужна переменная с именем _topSpeed ​​и Accessors с именами topSpeed ​​и setTopSpeed.
  4. @property (nonatomic) double topSpeed; - это , а не объявление чистой переменной, оно также будет объявлять методы доступа.Чистая переменная класса Foo будет выглядеть следующим образом:

    @ interface Foo: NSObject {double topSpeed;}

0 голосов
/ 03 марта 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...