Какой смысл вызывать «@synthesize slider = _slider;»

#ios #instance-variables

#iOS #переменные экземпляра

Вопрос:

Может кто-нибудь объяснить мне значение создания (того, что кажется) дополнительной переменной и зачем ставить символ подчеркивания перед новой переменной с тем же именем, что и у последней.

Я читал, что это связано с созданием переменных экземпляра, но зачем вам создавать элемент пользовательского интерфейса в качестве переменной экземпляра? Не могли бы вы предоставить пример использования?

Это код objective c для использования в разработке iOS.

Спасибо.

Ответ №1:

Когда вы @synthesize задаете свойство и не предоставляете свои собственные методы получения и установки (в этом случае в этом нет необходимости @synthesize ), всегда создается новая переменная экземпляра. По умолчанию он получает то же имя, что и свойство. Так @synthesize slider; создается переменная экземпляра с именем slider за кулисами.

Проблема здесь в том, что вы можете ошибочно ввести slider = xxx , когда вы действительно хотели использовать self.slider = xxx . Когда вы делаете что-то свойством, в рекомендациях говорится, что вы всегда должны обращаться к нему через self.propertyName (за исключением ваших методов init и dealloc и любых пользовательских методов получения и установки).

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

Комментарии:

1. «Когда вы делаете что-то свойством, лучшая практика гласит, что вы всегда должны обращаться к нему через self.propertyName» — почему это лучшая практика?

2. Потому что в этом суть свойств, что вы всегда проходите через их методы доступа. Получая прямой доступ к ivars, вы обходите это поведение.

Ответ №2:

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

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

 - (void)dealloc
{
    self.slider = nil;
    [super dealloc];
}
  

Поэтому обычно это делается вместо этого, что не вызовет KVO, поскольку вы не выполняете доступ к свойствам.

 - (void)dealloc
{
    [_slider release];
    [super dealloc];
}
  

Ответ №3:

Это обычно используется для синтеза свойства с частным префиксом или суффиксом ivar. Он пытается предотвратить случайный доступ к ivar, а не к свойству или переопределение ivar с помощью аргумента метода.

Рассмотрим это:

 @implementation MYClass
@synthesize flag = flag_;

- (void)doSomethingWithFlag:(BOOL)flag {
  if (flag) {
    // You do not need to worry about confusing the ivar
    // flag and the param flag because it is synthesized to flag_
  }
}

- (void)doSomething {
  if (flag) { // Doesn't work -> use accessor self.flag
    ...
  }
}

@end