Getter — это метод, который вызывается каждый раз, когда вы получаете доступ (считываете значение) к свойству (объявленному с помощью @property
). Все, что возвращает этот метод, считается значением этого свойства:
@property int someNumber;
...
- (int)someNumber {
return 42;
}
...
NSLog("value = %d", anObject.someNumber); // prints "value = 42"
Setter — это метод, который вызывается каждый раз при изменении значения свойства.
- (void)setSomeNumber: (int)newValue { // By naming convention, setter for `someValue` should
// be called `setSomeValue`. This is important!
NSLog("someValue has been assigned a new value: %d", newValue);
}
...
anObject.someNumber = 19; // prints "someValue has been assigned a new value: 19"
Обычно не имеет особого смысла просто возвращать одно и то же значение из геттера и печатать новое значение в сеттере. Чтобы на самом деле что-то сохранить, вам нужно объявить переменную экземпляра (ivar) в своем классе:
@interface SomeClass : NSObject {
int _someNumber;
}
и сделайте аксессоры (коллективное имя для геттеров и сеттеров) для хранения/получения его значения:
- (int)someNumber {
return _someNumber;
}
- (void)setSomeNumber:(int)newValue {
_someNumber = newValue;
}
...
SomeClass *anObject = [[SomeClass alloc]init];
anObject.someNumber = 15;
NSLog(@"It's %d", anObject.someNumber); // prints "It's 15"
Хорошо, теперь это свойство ведет себя как обычная переменная. Какой смысл писать весь этот код?
Во-первых, с этого момента вы можете добавить дополнительный код к средствам доступа, которые будут выполняться каждый раз при доступе к свойству или его изменении. Для этого есть несколько причин, например, я могу захотеть выполнить какие-то скрытые вычисления или обновить состояние моего объекта, кэшировать вещи и т. д.
Во-вторых, в Cocoa есть классные механизмы, называемые Key-Value Coding (KVC) и Key-Value Observing (KVO). Они зависят от свойств. Вы можете прочитать о них в библиотеке для разработчиков: Руководство по программированию KVC и Руководство по программированию KVO. Хотя это продвинутые темы.
Наконец, в Objective C нет статического размещения объектов. Все объекты распределяются динамически (причина ). Если вы хотите сохранить указатели объектов в переменных экземпляра (в отличие от свойств), вам придется выполнять все управление памятью вручную каждый раз, когда вы присваиваете новое значение вашему ivar (не верно, когда Автоматический подсчет ссылок включен). Используя свойства, вы можете поместить некоторый код управления памятью в аксессоры и сделать свою жизнь проще.
Я не думаю, что это объяснение будет иметь смысл для тех, кто не знаком с управлением памятью в Objective C, поэтому либо прочитайте некоторые настоящие документы/учебники по нему, либо просто используйте свойства (вместо переменных экземпляра), пока не изучите все детали так или иначе. Лично мне второй вариант не нравится, но решать вам.
Вы можете использовать @synthesize
, чтобы компилятор автоматически генерировал базовые методы доступа и базовые переменные экземпляра. Вместо приведенного выше кода (-(int)someNumber
и -(void)setSomeNumber:
) вы можете просто написать
@synthesize someNumber = _someNumber; // = _someNumbers tells compiler
// to name the instance variable `_someNumber`.
// You could replace it with = `_somethingElse`, of
// course, but that's an ill idea.
Эта единственная строка генерирует для вас int _someNumber
переменную, someNumber
геттер и setSomeNumber
сеттер. Если вы хотите, чтобы методы доступа делали что-то более сложное, чем просто сохранение/извлечение значения из некоторой переменной экземпляра, вам придется написать их самостоятельно.
Надеюсь, все это имеет какой-то смысл.
person
zrslv
schedule
03.05.2012