Свойства могут быть объявлены везде, где объявляются методы, например, в разделе интерфейса заголовочного файла с расширением ,h, в расширении класса или объявлении протокола. Ниже схематически показан синтаксис объявления свойства.

 

^property (атрибут, атрибут, ...) тип имя;

Вот пример объявления свойства:

Sproperty (nonatomic, strong) NSMutableArray* theData;

Обычно тип и имя соответствуют типу и имени переменной экземпляра, но на самом деле они обозначают имя свойства (в записи через точку), а также имена используемых по умолчанию set-метода (setTheData:) и get-метода (theData) наряду с типом значения, передаваемого set-методу установки и возвращаемого get-методом. Если данное свойство может быть представлено выходом в nib-файле, то перед типом можно указать IBOutlet. Это всего лишь указание для среды Xcode, не имеющее формального значения.

В качестве типа совсем не обязательно указывать тип объекта. Это может быть простой тип, в том числе BOOL, CGFloat или CGSize. Разумеется, в этом случае никакого управления памятью не происходит, поскольку оно и не требуется, и поэтому никакой стратегии управления памятью не должно быть объявлено, но преимущества применения свойства остаются. В частности, методы доступа могут быть синтезированы, а переменная экземпляра объявлена автоматически.

Ниже перечислены значения, которые может принимать атрибут.

Стратегия управления памятью

Имена этих стратегий перечислены в предыдущем разделе. В качестве атрибута указывается конкретная стратегия управления памятью. Если же действует механизм ARC, то обычно указывается стратегия strong; она же выбирается по умолчанию, если при действии механизма ARC стратегия управления памятью вообще опускается в объявлении свойства.

nonatomic

Если опустить это значение атрибута, в методах доступа будет применяться блокировка для обеспечения правильной работы приложения, при условии, что оно является многопоточным. Установка этого значения атрибута редко вызывает осложнения, тогда как блокировка замедляет работу методов доступа. Поэтому значение атрибута nonatomic чаще всего указывается в объявлении свойства. К сожалению, это значение не выбирается по умолчанию, но тут уж ничего не поделаешь. Для того чтобы компилятор выдавал предупреждение, если значение атрибута nonatomic случайно опущено, можно также установить режим построения Implicit Atomic Objectlve-C Properties.

readwrite или readonly

Если эти значения атрибута опущены, то по умолчанию выбирается значение readwrite. Если указано значение атрибута readonly, то любая попытка вызвать метод установки или воспользоваться свойством в качестве метода установки приведет к ошибке компилятора. Если должны быть синтезированы методы установки, то ни один из них не будет синтезирован.

getter-gname, setter-sname:

По умолчанию из имени свойства выводятся имена get- и set-методов, вызываемых при использовании этого свойства. Так, если свойство называется myProp, то по умолчанию для get-метода выбирается имя myProp, а для set-метода — имя setMyProp:. Для того чтобы изменить это положение, можно использовать любое или оба эти значения атрибутов. Так, если указать getter=beeblebrox при объявлении свойства, то get-метод для получения этого свойства будет называться beeblebrox. Если методы доступа синтезируются, то get-методу получения будет присвоено такое же самое имя. Это никак не отразится на пользователях данного свойства, но явный вызов метода доступа по несуществующему имени приведет к ошибке компилятора.

Для того чтобы объявить свойство закрытым, достаточно разместить его в расширении класса (см. главу 10). Чаще всего расширение класса размещается в самом начале файла реализации с расширением .т, т.е. до раздела реализации. В итоге имя свойства может использоваться как в самом классе, так и при вызове методов доступа, но не в других классах, как показано в примере 12.10.

 

Пример 12.10. Объявление закрытого свойства

// MyClass.ш:

@interface MyClass О

Sproperty (nonatomic, strong) NSMutableArray* theData; II закрытое свойство Send

(^implementation MyClass // здесь следует другой код @end

 

Сведения о закрытых свойствах классов не наследуются их подклассами. В качестве выхода из этого положения можно перенести раздел интерфейса с расширением класса в отдельный заголовочный файл с расширением .h и затем организовать его импорт в файлах реализации как суперкласса, так и подкласса.

 

Размещать объявление свойства в расширении класса целесообразно еще и потому, что это позволяет переопределить свойство. Например, свойство можно объявить как доступное только для чтения (readonly) вне класса, но доступное для чтения и записи (readwrite) внутри класса. Для того чтобы реализовать такую возможность, достаточно объявить свойство как readonly в разделе инструмента заголовочного файла, где оно будет доступно извне, а затем переопределить его без атрибута readonly в расширении класса, определяемом в файле реализации, где оно будет доступно только в самом этом классе. Все остальные атрибуты должны совпадать в обоих объявлениях свойства. По умолчанию в отсутствие атрибута readonly выбирается атрибут readwrite, а следовательно, в этом классе можно вызвать метод установки или указать свойство в качестве левого значения выражения, тогда как в других классах оно будет недоступно.


 

 

 

Добавить комментарий