Как доступ к ivars напрямую отличается от доступа? - PullRequest
3 голосов
/ 31 октября 2011

Так что в некоторых кодах, которые я вижу, они получают доступ к объектам ivar напрямую, а не через методы доступа. Каковы преимущества использования их вместо аксессоров?

Так как бы это

thing = object->ivar 

отличается от этого?

thing = object.ivar

Спасибо.

Ответы [ 4 ]

2 голосов
/ 31 октября 2011

Прежде всего позвольте мне сказать, что я полностью ненавижу нотацию Objective-C. Он жертвует понятностью ради краткости, и это плохо. Фактически, два других ответа здесь показывают доказательство того, что вводит нотацию путаницы.

После того, как я пропустил разглагольствования, я сейчас попытаюсь ответить на вопрос.

Под капотом объекты Objective-C реализованы как указатели на структуры С. Вот почему

obj->ivar

иногда работает. Учитывая, что это структура C

(* OBJ) .ivar

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

Оператор точки при применении к объекту Objective-C (который является указателем, не забудьте) имеет совершенно другое значение. Это синтаксический сахар для отправки объекту сообщения доступа, означающего, что:

foo = obj.property;
obj.property = foo;

идентичен в действии

foo = [obj property];
[obj setProperty: foo];

Это все, что нужно для точечной записи. Если вы просматриваете свой код, заменяя все экземпляры первой формы на экземпляры второй формы, вы сделали все, что делает компилятор с точечной нотацией.

В частности

  • вам не нужно декларировать @property для использования точечной нотации. Вы можете объявить методы доступа set и get традиционным способом как методы Objective C, хотя определенно рекомендуется использовать объявления @property для вещей, которые являются логически свойствами.
  • вам не нужна переменная резервного копирования. Нет причин, по которым ваши геттеры и сеттеры не могут вычислять значения.

Учитывая вышесказанное, основное различие между obj->ivar и obj.ivar состоит в том, что первый изменяет ivar напрямую, а второй вызывает метод доступа, это означает, что последний может выполнять любые необходимые операции по управлению памятью (сохраняет, освобождает, копирует и т.д.), а также может вызывать наблюдение значения ключа.

2 голосов
/ 31 октября 2011

Это одна вещь с огромной разницей между c / c ++ и target-c.

В C / C ++ . обращается к переменной напрямую, а -> обращается к переменной, если это указатель на переменную, поэтому в основном это то же самое.

В Objective-C . - это ярлык для доступа к свойству с использованием функций установки и получения, и всегда с использованием этих функций. Вы не можете получить доступ к ivars с ним, если нет свойства с таким именем.

Некоторые говорят, что "грязно" разрешать прямой доступ к переменным. Если над кодом работает больше людей, то использовать методы доступа «чище», потому что в случае изменения переменных может быть проще отлаживать, так как вы всегда можете выйти из строя в установщике.

С ним можно даже делать "плохие" вещи, например:

NSArray *array = [NSArray alloc] init];
int count = array.count;
array.release;

технически это будет работать, потому что array.release - это сокращение для [array release], но это плохой стиль - использовать . для других вещей, а не для свойств.

0 голосов
/ 31 октября 2011

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

-(void)setFrame:(CGRect)frame
{
    if([self frameIsValid:frame])
    {
        if(self.flipsFrames)
        {
            frame.size = CGSizeMake(frame.size.height,frame.size.width);
        }
        [super setFrame:frame];
        [delegate viewSubclass:self ChangedFrameTo:frame];
    }
}

Здесь показаны четыре преимущества:

  • Возможность переопределения
  • Возможность проверки заданного значения
  • Возможность изменения заданного значения (используйте с осторожностью)
  • Aспособ реагирования на вызовы

Еще одно преимущество:

-(NSInteger) amountOfMinutes
{
    return amountOfSeconds * 60;
}

Вы можете использовать 1 ивар для нескольких свойств, экономя память и предотвращая / уменьшая избыточность, сохраняя при этом полезные различные форматы.

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

0 голосов
/ 31 октября 2011

Все ивары являются частными. Нет возможности получить к ним доступ непосредственно снаружи объекта. Таким образом, оба примера кода эквивалентны в терминах ObjC.

Когда вы звоните object.ivar, то, что вы действительно делаете, вызывает object s ivar селектор. Это может быть либо метод получения, который вы написали самостоятельно, либо, скорее, синтезированный метод получения, который вы создали с помощью @synthesize.

thing, однако, - это ивар. Ваш код будет вызывать селектор ivar на object и присваивать результат напрямую thing ivar вашего экземпляра.

Если бы вы вместо этого записали его как self.thing = object.ivar, то вы бы использовали метод установки вашего экземпляра для присвоения thing.

Некоторые из преимуществ использования аксессоров (в частности, синтезированных свойств) в ObjC - это соответствие KVO / KVC; лучшая поддержка параллелизма; контроль доступа (только чтение, чтение и запись); а также все преимущества, которые вам предоставляют аксессоры на любом другом языке OO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...