Я много раз обыскивал аксессоры ObjC и синтезированные аксессоры. Этот вопрос больше похож на вопрос «помогите мне решить проблему»; Я не ожидаю одного ответа, но я скорее ищу экспертов, чтобы взвесить этот аргумент.
В классе Cocoa Touch я написал бы такой код (где soundEffects
- это синтезированное свойство NSArray):
id foo = [self.soundEffects objectAtIndex:1];
Коллега попросил меня объяснить, почему вышеупомянутое лучше, чем эта строка:
id foo = [soundEffects objectAtIndex:1];
Ну, функционально, это ничем не отличается.
Мои аргументы в пользу первого заключаются в следующем:
self.soundEffects
сообщает каждому другому кодеру, работающему с кодом, что это iVar, а не локальная переменная.
Если нам когда-либо понадобилось, мы могли бы поместить пользовательскую логику в метод доступа get soundEffects
.
Без конкретной причины, после работы в Obj-C в течение года он чувствует себя как «правильно».
Он принимает аргументы № 1 и № 2 как действительные, но также дает контрапункт:
Разве это не просто раздувание кода ?
Разве нельзя разрешить классу напрямую общаться со своими собственными iVars, не вызывая метод (метод получения) для себя?
Любые получатели?
Ваш пункт 1 не совсем верен: self.soundEffects
is not ivar, хотя может случиться так, что вы получите что-то такое, что is - как это работает в случае вашего синтезированного NSArray
, на данный момент .
Это, в свою очередь, означает, что ваша точка 2 является сутью вопроса - если вы маршрутизируете весь доступ через аксессор, тогда все красиво инкапсулируется, и вы можете изменить реализацию позже, не беспокоясь о побочных эффектах. .
Это также хорошая практика, когда вы используете мутатор, чтобы поддерживать последовательное управление памятью.
По большей части, я бы сказал, что рекомендуется маршрутизировать через self.property
все, что является свойством, и ограничивать прямой доступ ivar к вещам, которые являются строго внутренними . Однако я допускаю, что в некоторых случаях - особенно для вещей, которые не используют , сохраняют семантику
/ copy
- это может быть скорее предпочтением стиля.
Я лично решил использовать префикс подчеркивания для ivars и такого рода синтез
@synthesize name = _name;
Таким образом, я не путаю их. Основная проблема с отказом от использования self заключается в том, что этот код
_name = ...
сильно отличается от
self.name = ...
, когда @property использует параметр сохранения. Первый не сохраняет объект, а второй вызывает синтезированный сеттер, который сохраняет.
Единственный раз, когда это имеет большое значение, - это присваивание, поэтому я предпочитаю использовать self.
постоянно, так что делаю это по заданию.
с использованием чего-то вроде self.variable = nil
заставляет переменную проходить через свой установщик и, следовательно, бесплатно управляет памятью. если вы просто используете variable = nil
, например, в методе dealloc, это вызовет утечку, поскольку на самом деле он не проходит через синтезированный установщик для переменной и не уменьшает счетчик сохранения. См. Этот пост утечка памяти с самим собой.
По этой причине рекомендуется (я считаю) всегда использовать self. при работе с переменными экземпляра, которыми вы владеете, что касается управления памятью.