Атрибуты свойств в Objective-C

Начиная с Objective C 2.0 появилось понятие - свойство, под свойство выделена директива @property, которая указывает, что данная переменная класса имеет метод для чтения и записи в нее. Данная директива объявляется в файле объявлении класса.

Сопутствующая директиве @property, директива говорящая компилятору, что необходимо создать методы для доступа к переменной носит наименование @synthesize и объявляется в файле реализации класса.

Начиная с Xcode 4.5 использование @synthesize в файле реализации стало необязательным. В этом случае в файле - заголовке объявляется свойство:
@property NSInteger a;
доступ к самой переменной будет начинаться с символа подчеркивания _a, а доступ к сеттеру или геттеру внутри класса:
[self a]

В скобках перечисляются атрибуты доступа к instance-переменной.


Имена акцессора и мутатора:

getter=метод геттера
  • Используется для задания имени функции, используемой для извлечения значения instance-переменной.

setter=метод сеттера
  • Используется для задания имени функции, используемой для установки значения instance-переменной.

Взаимоисключающие атрибуты ограничения чтения/записи:

readwrite
  • У свойства есть как акцессор, так и мутатор. Является атрибутом по умолчанию.
  • И чтение и запись.

readonly
  • У свойства есть только акцессор.
  • Только чтение.

Атрибуты мутатора (без ARC):

assign
  • Для задания нового значения используется оператор присваивания. Используется только для POD-типов (для скалярных типов (NSInteger и CGRect)) либо для объектов, которыми мы не владеем.
  • Без ARC assign при присваивании не увеличивает счетчик ссылок, при удалении объекта свойство будет указывать на не существующий объект. Важно: не становится nil т.е. указывает на неопределенное место в памяти. Нужно самостоятельно занулять.
Пример:
-(void)someSetter(id)newVar
{
    var = newVar;
}

retain
  • Указывает на то, что для объекта, используемого в качестве нового значения instance-переменной, управление памятью происходит вручную (не забываем потом освободить память).
  • Без ARC при присваивании увеличивает счетчик ссылок объекта, т.е. ты становишься владельцем.
  • retain, в отличие от copy не копирует объект при обращении к свойству, а увеличивает счетчик использований и возвращает тот же самый объект (как бы ссылку на объект). Это нужно, если объект большой или его не имеет смысла копировать. Например, объекты типа UIView, UIViewController, UIWindow.
  • retain - передача по ссылке, copy - по значению.
  • Атрибут retain обеспечивает присвоение значения экземплярной переменной в порядке retain-release.

Атрибуты мутатора (c ARC):

weak
  • Аналог assign при применении режима автоматического подсчёта ссылок. (ARC должен поддерживаться компилятором).
  • В отличии от strong обозначает нестрогое соответствие и если объект был освобожден из памяти (из другого класса или потока), то значение установится в nil. Не поддерживается OS X 10.6 и iOS 4; используйте assign.
  • С ARC weak не совсем аналог assign на самом деле. Действие похожее, но становиться nil если объект был удален. Т.е. более безопасно.
  • Если мы ведем речь про weak ссылки, то это что-то похоже на следующее: "Машина едет по дороге, у машины есть weak ссылка на дорогу. Дорога не зависит от машины, машина не зависит от дороги. Машина может легко поменять дорогу, а старая дорога останется там же где и была.".

strong
  • Аналог retain при применении режима автоматического подсчёта ссылок. (ARC должен поддерживаться компилятором).
  • Обозначает строгое переназначение объекта, делая указатель на объект владельцем этого объекта.
  • С ARC strong == retain.
  • Используем strong, если требуется, что бы один объект зависел от другого. В абстрактных примерах можно привести такой пример: "У машины колеса должны быть strong (retain). Если удаляется машина, то обязательно удаляются его колеса".

Атрибуты мутатора:

copy
  • Указывает на то, что для присваивания будет использована копия переданного объекта.
  • Первоначальному объекту посылается сообщение release. Может быть использовано только для объектов, поддерживающих протокол NSCopying, например NSString.
  • Копирует и возвращает удержанный объект (объект не удалится).
  • Атрибут copy обеспечивает присвоение значения экземплярной переменной в порядке copy-release.

Atomic:

nonatomic
  • Делает более быстрым способ доступа к объекту в немногозадачной среде, так-как в случае с atomic (по умолчанию все акцессоры atomic) и использованием strong, copy, или retain, во избежание коллизий с возможностью доступа к свойству из других потоков в сеттере строится код блокирующий переключение между потоками.
  • Ключевое словом nonatomic означает, что при генерации реализаций сеттера и геттера (@synthesize) компилятор не будет вставлять блокировки для корректного обращения к свойству из разных потоков. То есть nonatomic означает "потоконебезопасный". nonatomic в большинстве случаев предпочтителен, т. к. сеттер и геттер работают быстрее.
  • Атрибут nonatomic ускоряет работу акцессора: атомарные свойства нужны только при работе с множественными потоками (threads).

--