В Objective-C на iOS, в чем (стиль) разница между "self.foo" и "foo" при использовании синтезированных геттеров? - PullRequest
13 голосов
/ 16 августа 2010

Я искал много вопросов о средствах доступа ObjC и синтезированных средствах безрезультатно.Этот вопрос больше похож на вопрос «помогите мне решить проблему»;Я не ожидаю одного ответа, но я скорее ищу экспертов, чтобы взвесить аргумент.

В классе Cocoa Touch я написал бы такой код (где soundEffects - синтезированныйСвойство NSArray):

id foo = [self.soundEffects objectAtIndex:1];

Коллега попросил меня объяснить, почему вышеупомянутое лучше, чем эта строка:

id foo = [soundEffects objectAtIndex:1];

Ну, функционально это ничем не отличается.

Мои аргументы для первого из них следующие:

  1. self.soundEffects говорит каждому другому кодеру, работающему с кодом, что это iVar, а не переменная с локальной областью видимости.

  2. Если бы нам когда-либо понадобилось, мы могли бы поместить собственную логику в метод доступа геттера soundEffects.

  3. Без какой-либо конкретной причины, это "после работы в Obj-C в течение года он чувствует себя как «правильное».

Он принимает аргументы № 1 и № 2 как действительные, но также дает контрапункт:

  1. Разве это не просто раздувание кода?

  2. Разве нельзя разрешить классу напрямую общаться со своими собственными iVars без вызова метода (геттер) на себя?

Любые берут?

Ответы [ 4 ]

9 голосов
/ 16 августа 2010

Я лично решил использовать префикс подчеркивания для иваров, и этот вид синтеза

@synthesize name = _name;

Таким образом, я не путаю их. Основная проблема с неиспользованием self заключается в том, что этот код

_name = ...

очень отличается от

self.name = ...

Когда @property использует опцию сохранения. Первый не сохраняет объект, а второй вызывает синтезированный установщик, который сохраняет.

Единственный раз, когда это имеет большое значение, это назначение, поэтому я склонен использовать self. все время, поэтому я проверяю, что делаю это на назначениях.

5 голосов
/ 16 августа 2010

Ваша точка 1 не совсем верна: self.soundEffects является , а не иваром, хотя может случиться так, что вы получите нечто, что равно - как это происходит в случае ваш синтезированный NSArray, на данный момент .

Это, в свою очередь, означает, что ваша точка 2 - суть вопроса - если вы перенаправите весь доступ через аксессор, то все будет хорошо инкапсулировано, и вы сможете позже изменить реализацию, не беспокоясь о побочных эффектах. .

Это также хорошая практика, когда вы используете мутатор, поэтому вы поддерживаете согласованное управление памятью.

По большей части я бы сказал, что желательно проложить маршрут через self.property для всего, что является свойством, и ограничить прямой доступ ivar к вещам, которые являются строго внутренними. Однако я признаю, что в некоторых случаях - особенно для вещей, которые не используют семантику retain / copy - это может быть больше предпочтением стиля.

4 голосов
/ 16 августа 2010

используя что-то вроде self.variable = nil заставляет переменную проходить через ее установщик и, следовательно, получает память, управляемую бесплатно.если вы просто используете variable = nil, например, в методе dealloc, это вызовет утечку, так как фактически она не проходит через синтезированный установщик для переменной и уменьшает счет сохранения.См. Этот пост утечка памяти с самим собой.

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

1 голос
/ 17 мая 2013

self.soundEffects
устанавливает / получает переменную экземпляра через метод установки / получения, и, следовательно, если мы хотим выполнять некоторые пользовательские операции при изменении их значения, эта логика может идти в их метод получения / установки.

Также согласно ios 6, ивар соответствует

@property (nonatomic)NSArray *propertyName;

будет

_propertyName

так что я думаю, вы больше не можете использовать

id foo = [soundEffects objectAtIndex:1];
. Не уверен, однако. Вместо этого вам следует использовать
id foo = soundEffects[1];
...