Свойство представляет собой синтаксическую возможность современного языка программирования Objective-C, разработанную в качестве альтернативы стандартному синтаксису методов доступа.

В качестве синтаксического приема, облегчающего программирование, вы можете просто добавить имя свойства к ссылке на экземпляр с помощью записи с точкой. Получающееся в результате выражение можно использовать как слева от знака равенства (для вызова соответствующего метода доступа для установки значения), так и в любых других местах (для вызова соответствующего метода доступа для получения значения). Имя свойства по умолчанию использует соглашения по именованию методов доступа.

Я воспользуюсь в качестве примера классом Dog. Если класс Dog имеет открытый метод доступа для получения значения переменной экземпляра с именем number и открытый метод доступа для установки setNumber:, то класс Dog имеет также свойство number, которое может быть использовано слева от знака равенства или в любом ином месте. Это означает, что вместо

[fido setNumber: 42];
int n = [fido number];
можно записать
fido.number = 42;
int n = fido.number;

Применение свойств совершенно не обязательно. Наличие свойства эквивалентно наличию соответствующих методов доступа к данным; использование свойства эквивалентно вызову метода доступа. Вызывать метод доступа можно с помощью любого синтаксиса. В случае класса Dog вы можете как вызывать методы доступа для установки и получения значения переменной экземпляра (number и setNumber:), так и воспользоваться свойством (number).

Для того чтобы использовать свойство в классе, которое им обладает, следует явно указывать ключевое слово self, например

self.number = 42;

 

Не путайте свойство с переменной экземпляра. Выражение наподобие self->number = п, или даже просто number = п, устанавливает значение переменной экземпляра непосредственно (и это возможно только в самом классе, поскольку переменные экземпляров по умолчанию являются защищенными).Выражение наподобие fido. number или self .number включает свойство и эквивалентно вызову метода доступа. Такой метод доступа может обращаться к переменной экземпляра, и эта переменная экземпляра может даже иметь то же имя, что и свойство, но это не означает, что они представляют собой одну и ту же сущность.

 

К свойствам мы вернемся в главе 12, где вы узнаете, что на самом деле это более мощная и интересная возможность, чем я рассказал здесь. Сейчас я говорю о свойствах просто потому, что они широко применяются в каркасе Cocoa и поскольку вам очень часто придется сталкиваться с ними в документации.

Например, ранее в этой главе я вызывал метод экземпляра setFrame: класса UlView с экземпляром класса UIButton:

[Ъ setFrame: CGRectMake(100,100,52,30)];

Я упоминал, что setFrame: не документирован в UIButton; вы должны обратиться к документации по UlView. Но в действительности такой метод не описан и там. Вот что говорит документация UlView по этому поводу.

frame

• Прямоугольник рамки, описывающий положение и размер представления в координатной системе родительского представления.

• ^property(nonatomic) CGRect frame

В документации говорится о том, что у класса UlView есть свойство с именем frame. Приведенная выше строка является объявлением свойства. С точки зрения клиента класса UlView — в данном случае с моей точки зрения — объявление свойства является просто сокращенной записью, говорящей, что такое свойство существует. (Пока что не будем говорить о смысле ключевого слова nonatomic.) Но это то же самое, что сказать о наличии в классе UlView методов экземпляра frame и setFrame:; я могу использовать эти методы либо посредством свойства frame и записи с точкой, либо явно их вызывая. Таким образом я и узнал о существовании метода доступа setFrame:. В моем коде я вызвал setFrame: явно; но сейчас вы уже знаете, что я мог бы воспользоваться свойством frame:

b.frame = CGRectMake<100,100,52,30);

Язык Objective-C для свойств использует запись с точкой, а язык С использует такую запись для структур; эти записи могут быть объединены в цепочки. Так, например, свойство frame класса UlView является свойством, значение которого представляет собой структуру (CGRect); таком образом, можно записать myView. frame. size. height, где frame представляет собой свойство, возвращающее структуру, size является элементом этой структуры, a height, в свою очередь, элементом структуры size. У этого синтаксиса имеются ограничения; вы не можете, например, непосредственно установить значение height с помощью цепочки, начинающейся с UlView:

myView.frame.size.height =36.0; // Ошибка "Expression is not assignable”

Вместо этого, если вы хотите изменить компонент свойства, являющегося структурой, вы должны получить значение свойства в переменную структуры, изменить ее значение и установить значение всего свойства, используя эту переменную:

CGRect f = myView.frame;
f.size.height = 0;
myView.frame = f;

 

 

 

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