В Objective-C на iOS, что такое (стиль) различие между "self.foo" и "foo" при использовании синтезированных геттеров?
Я искал много вопросов об объектах ObjC и синтезированных аксессуарах безрезультатно. Этот вопрос больше связан с вопросом "помогите мне решить вопрос"; Я не ожидаю ответа, но я скорее ищу экспертов для взвешивания аргументов.
В классе Cocoa Touch я бы написал такой код (где soundEffects
- синтезированное свойство NSArray):
id foo = [self.soundEffects objectAtIndex:1];
Коллега попросил меня объяснить, почему выше это лучше, чем эта строка:
id foo = [soundEffects objectAtIndex:1];
Ну, функционально, это ничем не отличается.
Мои аргументы для первого:
-
self.soundEffects
указывает каждому другому кодеру, работающему над кодом, что это iVar, а не локальная область.
-
Если нам когда-либо понадобится, мы могли бы поместить пользовательскую логику в аксессуар soundEffects
getter.
-
По какой-то конкретной причине он "чувствует", как правильно, что нужно делать после работы в Obj-C в течение года.
Он принимает аргументы # 1 и # 2 как действительные, но также дает контрапункт:
Любые участники?
Ответы
Ответ 1
Ваша точка 1 не совсем правильная: self.soundEffects
не является ivar, хотя может случиться, что вы получите что-то, что есть, как в случае с вашим синтезированным NSArray
, на данный момент.
Это, в свою очередь, подразумевает, что ваша точка 2 является главной проблемой - если вы направляете весь доступ через аксессуар, тогда все прекрасно инкапсулируется, и вы можете свободно модифицировать реализацию позже, не беспокоясь о побочных эффектах.
Это также хорошая практика при использовании мутатора, поэтому вы поддерживаете постоянное управление памятью.
По большей части, я бы сказал, что желательно пройти через self.property
для всего, что является свойством, и ограничить прямой доступ к IVAR для вещей, которые являются строго внутренними. Тем не менее, я признаю, что в некоторых случаях - особенно для вещей, которые не используют семантику retain
/copy
- это может быть больше предпочтений стиля.
Ответ 2
Я лично решил использовать префикс подчеркивания для ivars, и этот вид синтеза
@synthesize name = _name;
Таким образом я не смешиваю их. Основная проблема не в том, что я использую сам, так это то, что этот код
_name = ...
сильно отличается от
self.name = ...
Когда @property использует опцию сохранения. Первый не сохраняет объект, а второй вызывает синтезированный сеттер, который сохраняет.
Единственный раз, когда это имеет большое значение, заключается в назначении, поэтому я обычно использую self.
все время, поэтому я уверен, что я делаю это при назначении.
Ответ 3
используя что-то вроде self.variable = nil
, переменная переходит через свой сеттер и, следовательно, получает доступную память. если вы просто используете variable = nil
, например, в методе dealloc, это вызовет утечку, поскольку на самом деле он не проходит через синтезированный сеттер для переменной и не уменьшает счетчик сохранения. См. Это сообщение утечка памяти с самим собой.
По этой причине, желательно (я считаю) всегда использовать себя. при работе с переменными экземпляра, которыми вы владеете, в том, что касается управления памятью.
Ответ 4
self.soundEffects
устанавливает/получает переменную экземпляра через setter/getter, и, следовательно, если мы хотим выполнять некоторые пользовательские операции, когда их значение изменяется, эта логика может идти в их getter/setter.
Также согласно ios 6, ivar, соответствующий
@property (nonatomic)NSArray *propertyName;
будет
_propertyName
поэтому я предполагаю, что вы не можете использовать
id foo = [soundEffects objectAtIndex:1];
больше. Не уверен, хотя. Вместо этого вы должны использовать id foo = soundEffects[1];