Параметры скрывают переменные экземпляра в Objective-C

Есть ли способ дать параметру метода то же имя, что и переменная экземпляра в Objective-C, не скрывая эту переменную?

Например,

- (void)doSomething:(id)object
{
    self.object = object;
}

Приведенный выше код выдает предупреждение: «Локальное объявление объекта скрывает переменную экземпляра».

Очевидное решение состоит в том, чтобы назвать аргументы параметра по-другому, но меня раздражает необходимость выбирать имя, например, «anObject» вместо «object».


person titaniumdecoy    schedule 11.08.2009    source источник
comment
Когда вы говорите о локальной переменной, я думаю, вы имеете в виду переменную экземпляра. Параметры — это один из видов локальных переменных.   -  person outis    schedule 11.08.2009
comment
Спасибо аутис. Я исправил вопрос.   -  person titaniumdecoy    schedule 11.08.2009


Ответы (2)


Вы можете использовать точечную нотацию для доступа к свойствам (как в примере), но переменные экземпляра имеют только один путь доступа, поэтому единственное решение, если вы хотите получить доступ как к переменной экземпляра, так и к локальной переменной, — дать им разные имена.

Формально это связано с ограничениями на альфа-преобразование в лямбда-исчисление, в частности, что связанная переменная должна оставаться связанной, а свободная переменная должна оставаться свободной.

Если вам не нравится префикс «an» для локальных переменных, вы можете использовать соглашение о префиксе «_» для переменных экземпляра, поскольку они также являются эффективно защищенными переменными.

@interface AClass {
    id _object;
}
@property (retain) id object;
@end

@implementation AClass
@synthesize object = _object;

- (void)doSomething:(id)object
{
    [_object befriend:object];
}
...

Конечно, "_" читается как "мой", так что это может быть так же неприятно, как "a"/"an" перед параметрами. Переименование — лучшее решение, поскольку экземпляр и локальные переменные имеют разные роли, и их имена должны это отражать.

person outis    schedule 11.08.2009
comment
На самом деле, вы можете получить доступ к иварам с помощью self-›object. Кроме того, Apple резервирует префикс подчеркивания для собственного использования, хотя, похоже, никто не обращает на это внимания. Лично я использую i_ в качестве префикса для своих иваров, что также помогает отличить их от свойств. - person Peter N Lewis; 11.08.2009
comment
Добавление подчеркивания также позволяет различать _object = something и self.object = something, которые представляют собой два совершенно разных фрагмента кода. - person kubi; 11.08.2009
comment
Что, если рассматриваемый метод на самом деле является установщиком для переменной экземпляра? Что-то другое? - person Tony; 08.12.2011
comment
@Tony: подумай об этом немного. Что случилось бы? Как только вы подумали об этом, попробуйте в отладчике. - person outis; 08.12.2011
comment
@Peter: на самом деле символ подчеркивания, зарезервированный Apple, относится только к внутренним библиотекам кода Apple. Для вашего собственного кода вы можете использовать имена переменных с префиксом подчеркивания, и Apple фактически упоминает, что префиксы подчеркивания могут использоваться для обозначения разницы между экземпляром _variable и его методом доступа self.variable. (см. developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/) Лично я бы вообще не ставил префикс экземпляра vars, а скорее менял бы имена параметров метода. - person LearnCocos2D; 02.03.2012
comment
Я считаю, что Apple резервирует префикс подчеркивания только для имен методов, а не для иваров. Xcode автоматически дополняет ивары, начинающиеся со знака подчеркивания (т. е. @synthesize myVar = _ автоматически заполняет _myVar. - person titaniumdecoy; 02.03.2012

Вы могли бы сделать что-то вроде self->object = object, но соглашение Objective-C (производное от Smalltalk) состоит в том, чтобы префиксировать параметры с "a" или "an", если параметр имеет то же имя, что и переменная экземпляра.

person mipadi    schedule 11.08.2009
comment
+1 за этот ответ. Общедоступные API-интерфейсы Cocoa используют имена параметров, такие как anObject и aDictionary, чтобы отличать их от переменных экземпляра. В дополнение к соблюдению соглашения это снижает вероятность случайного обращения к неправильной переменной и несколько упрощает рефакторинг. - person Quinn Taylor; 11.08.2009
comment
Это решение, рекомендованное Apple, плюс это хорошая конвенция, IMO. - (void)doSomething:(id)anObject. - person andyvn22; 11.08.2009