Ответ 1
Getter - это метод, который вызывается каждый раз, когда вы получаете доступ (считываете значение) из свойства (объявляется с помощью @property
). Независимо от того, что возвращает этот метод, считается, что значение свойства:
@property int someNumber;
...
- (int)someNumber {
return 42;
}
...
NSLog("value = %d", anObject.someNumber); // prints "value = 42"
Сеттер - это метод, который вызывается каждый раз при изменении значения свойства.
- (void)setSomeInt: (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"
Обычно нет смысла просто возвращать одно и то же значение из getter и печатать новое значение в setter. Чтобы фактически сохранить что-то, вы должны объявить переменную экземпляра (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 %d", anObject.someNumber); // prints "It 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 an ill idea.
Эта единственная строка генерирует переменную int _someNumber
, someNumber
getter и setSomeNumber
setter для вас. Если вы хотите, чтобы аксессоры делали что-либо более сложное, чем просто хранить/извлекать значение из какой-либо переменной экземпляра, вам придется писать их самостоятельно.
Надеюсь, что все это имеет смысл.