У декларируемых свойств требуется соответствующая переменная экземпляра?

В свойствах Objective-C 2.0 требуется указать соответствующую переменную экземпляра? Например, я привык делать что-то вроде этого:

myobject.h

@interface MyObject : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end

MyObject.m

@implementation
@synthesize name;
@end

Однако, если бы я сделал это вместо:

myobject.h

@interface MyObject : NSObject {
}
@property (nonatomic, retain) NSString *name;
@end

Это все еще актуально? И разве это по-другому отличается от моего предыдущего примера?

Ответ 1

Если вы используете Modern Objective-C Runtime (или iOS 3.x или выше, либо 64-бит Snow Leopard или выше), вам нужно не определить ivars для ваших свойств в таких случаях.

Когда вы @synthesize свойство, ивар будет синтезироваться также для вас. Это происходит вокруг сценария "хрупкий-ивар". Вы можете больше узнать об этом на Cocoa с любовью

Ответ 2

В вашем интерфейсе вы можете официально объявить переменную экземпляра между фигурными скобками или через @property вне фигурных скобок или оба. В любом случае, они становятся атрибутами класса. Разница в том, что если вы объявляете @property, вы можете реализовать с помощью @synthesize, который автоматически кодирует ваш приемник/сеттер для вас. Например, набор автокодеров инициализирует целые числа и числа с плавающей запятой. ЕСЛИ вы объявляете переменную экземпляра и НЕ указываете соответствующий @property, тогда вы не можете использовать @synthesize и must писать свой собственный приемник/сеттер.

Вы всегда можете переопределить автозатемненный геттер/сеттер, указав свой собственный. Обычно это делается с помощью свойства managedObjectContext, которое загружается лениво. Таким образом, вы объявляете свой managedObjectContext как свойство, но затем также записываете метод -(NSManagedObjectContext *)managedObjectContext. Напомним, что метод, который имеет то же имя, что и переменная/свойство экземпляра, является методом "getter".

Метод объявления @property также позволяет вам использовать другие параметры, такие как retain и readonly, которые не имеют метода декларации переменных экземпляра. В принципе, ivar является старым способом, а @property расширяет его и делает его более привлекательным/легким. Вы можете ссылаться либо на использование себя. префикс или нет, это не имеет значения, если имя уникально для этого класса. В противном случае, если ваш суперкласс имеет то же имя свойства, что и вы, то вы должны сказать либо как self.name или super.name, чтобы указать, какое имя вы говорите.

Таким образом, вы увидите, что все меньше и меньше людей объявляют ivar между фигурными скобками и вместо этого переходят к простому указанию @property, а затем выполняют @synthesize. Вы не можете выполнить @synthesize в своей реализации без соответствующего @property. Синтезатор знает только, какой атрибут он имеет в спецификации @property. Оператор synhesize также позволяет вам переименовывать свойства, чтобы вы могли ссылаться на свойство по одному имени (сокращению) внутри вашего кода, но снаружи в файле .h используйте полное имя. Тем не менее, с действительно крутой автозаполнением, которое XCode теперь имеет, это менее выгодно, но все еще там.

Надеюсь, что это поможет прояснить всю путаницу и дезинформацию, которая плавает вокруг.

Ответ 3

он работает в обоих направлениях, но если вы не объявляете их в фигурных скобках, вы не увидите их значения в отладчике в xcode.

Ответ 4

Из документации:

В целом поведение свойств идентично как для современных, так и для устаревших версий (см. "Версии среды выполнения и платформы" в Objective-C Руководстве по программированию времени выполнения). Существует одно ключевое отличие: современная среда исполнения поддерживает синтез переменных экземпляра, тогда как устаревшая среда выполнения не делает.

Для @synthesize для работы в устаревшей среде выполнения вы должны либо предоставить переменную экземпляра с тем же именем и совместимым типом свойства, либо указать другую существующую переменную экземпляра в операторе @synthesize. С помощью современной среды выполнения, если вы не предоставляете переменную экземпляра, компилятор добавляет ее для вас.

Ответ 5

Если вы используете XCode 4.4 или более позднюю версию, он будет генерировать код синтеза переменных экземпляра для вас.

Вам просто нужно объявить свойства, как показано ниже; он будет генерировать для вас код для кодирования кода и экземпляра.

@property (nonatomic, strong) NSString *name;

он будет генерировать синтезирующий код как

@synthesize name = _name;

и вы можете получить доступ к переменной экземпляра, используя _name он похож на declare

NSString* _name

но если вы объявляете свойство только для чтения, оно похоже на

@property (nonatomic, strong, readonly) NSString *name;

он сгенерирует код

@synthesize name;

или

@synthesize name = name; 

Итак, вы должны получить доступ к имени текущей переменной без префикса "_" любым способом вы можете написать свой собственный синтезирующий код, тогда компилятор будет генерировать код для вас. вы можете написать

@synthesize name = _name;

Ответ 6

Objective-C Язык программирования: директивы по внедрению свойств

Существуют различия в поведении синтезатора доступа, зависящие от времени выполнения (см. также "Разница времени выполнения" ):

  • Для устаревшей среды выполнения переменные экземпляра уже должны быть объявлены в блоке @interface текущего класса. Если существует переменная экземпляра с тем же именем, что и свойство, и если его тип совместим с типом свойств, он используется, иначе вы получите ошибку компилятора.

  • Для современных сред выполнения (см. "Версии среды выполнения и платформы" в Objective-C Руководство по программированию времени выполнения) переменные экземпляра синтезируются по мере необходимости. Если переменная экземпляра с тем же именем уже существует, она используется.