У декларируемых свойств требуется соответствующая переменная экземпляра?
В свойствах 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 Руководство по программированию времени выполнения) переменные экземпляра синтезируются по мере необходимости. Если переменная экземпляра с тем же именем уже существует, она используется.