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

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

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

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

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

id foo = [soundEffects objectAtIndex:1];

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

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

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

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

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

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

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

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

Любые получатели?

13
задан makdad 16 August 2010 в 14:38
поделиться

3 ответа

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

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

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

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

5
ответ дан 1 December 2019 в 23:13
поделиться

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

@synthesize name = _name;

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

_name = ...

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

self.name = ...

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

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

9
ответ дан 1 December 2019 в 23:13
поделиться

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

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

4
ответ дан 1 December 2019 в 23:13
поделиться