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

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

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


person GenieWanted    schedule 03.05.2012    source источник


Ответы (3)


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

«Геттеры» и «сеттеры» используются для управления изменениями переменной (поля).

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

Часто «сеттер» сопровождается «геттером» (также известным как метод доступа), который возвращает значение закрытой переменной-члена.

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

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

person Community    schedule 03.05.2012

«Геттеры» и «сеттеры» свойств в большинстве любых объектно-ориентированных языков предоставляют «внешний» или пользовательский интерфейс вокруг закрытых членов экземпляров ваших классов. Некоторые критики объектно-ориентированного программирования назовут их «синтаксическим сахаром», но все сводится к тому, что потребители ваших классов будут использовать эти интерфейсы, которыми вы управляете программно, а не обращаться к фактически. em> сами частные члены. Таким образом, вы можете (например) защитить приватную переменную от получения недопустимого значения или значения, выходящего за пределы диапазона, или сделать свойство доступным только для чтения, предоставив только геттер, но не сеттер. Еще более интересной является идея о том, что геттеры и сеттеры могут обертывать свойства, которые изначально не сохраняются в вашем классе, но могут (например) вычисляться на основе других членов экземпляра.

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

Удачи.

person David W    schedule 03.05.2012