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


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

Мой_объект.h

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

Мой_объект.м

@implementation
@synthesize name;
@end

однако, что делать, если я сделал это вместо:

Мой_объект.h

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

Это все еще действует? И чем он отличается от моего предыдущего примера?

6 102

6 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

@property (nonatomic, strong) NSString *name;

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

@synthesize name = _name;

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

NSString* _name

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

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

он будет генерировать код

@synthesize name;

или

@synthesize name = name; 

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

@synthesize name = _name;

Язык Программирования Objective-C: Директивы Реализации Свойств

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

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

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