Подтвердить что ты не робот

Пожалуйста, объясните Getter и Setters в Objective C

Возможный дубликат:
Setters and Getters (Noobie) - iPhone SDK

Я новичок здесь. Я только начал изучать iOS в течение последних двух месяцев, и у меня нет программирования. (Хотя немного Java, хотя). Может кто-нибудь объяснить, что такое getter и setter в Objective C? Какая польза от них? Почему мы используем @property и @synthesize?

4b9b3361

Ответ 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 для вас. Если вы хотите, чтобы аксессоры делали что-либо более сложное, чем просто хранить/извлекать значение из какой-либо переменной экземпляра, вам придется писать их самостоятельно.

Надеюсь, что все это имеет смысл.

Ответ 2

"Getters" и "seters" используются для управления изменениями в переменной (поле).

"setter", чаще всего используется в объектно-ориентированном программировании в соответствии с принципом инкапсуляции. Согласно этому принципу переменные-члены класса становятся закрытыми, чтобы скрыть и защитить их от другого кода и могут быть изменены только публичной функцией-членом, которая принимает требуемое новое значение в качестве параметра, дополнительно проверяет его и изменяет переменная частного члена.

Часто "сеттер" сопровождается "getter" (также известный как accessor), который возвращает значение частной переменной-члена.

Методы Getter/Setter могут также использоваться в не-объектно-ориентированных средах. В этом случае ссылка на переменную, подлежащую изменению, передается методу вместе с новым значением. В этом случае компилятор не может ограничивать использование кода в обход методов getter/setter и напрямую изменять переменную. Брандмауз приходится на разработчиков, чтобы гарантировать, что переменная изменяется только этими методами и не изменяется напрямую.

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

Ответ 3

Свойство "getters" и "seters" в большинстве любых объектно-ориентированных языков предоставляет "внешний" или пользовательский интерфейс вокруг частных членов экземпляров ваших классов. Некоторые критики OO будут ссылаться на них как на "синтаксический сахар", но то, что он сводит к минимуму, заключается в том, что потребители ваших классов будут использовать эти интерфейсы, которые вы будете контролировать программным путем, а не обращаться к самим фактическим частным пользователям. Таким образом, вы можете (например) защитить приватную переменную от получения недопустимого или вне диапазона значения или сделать свойство доступным только для чтения, предоставляя только геттер, но не устанавливающий. Еще более интересна идея о том, что getters и seters могут переносить свойства, которые не сохраняются в вашем классе, но могут (например) вычисляться на основе других членов экземпляра.

Getters и seters наверняка не уникальны для Objective-C; если вы продолжите программирование на других языках OO, вы найдете их в С#, Java и других.

Удачи.