Соглашение об именах iPhone ivar
Возможный дубликат:
Как подчеркивается символ подчеркивания перед переменной в классе cocoa objective-c?
Я заметил, что во многих справочных материалах я вижу, что много времени переменные называются _variable в файле .h, а затем @synhesize'd в .m файле как
@synthesize variable = _variable;
Почему это сделано? Что мне не хватает?
Спасибо!
Ответы
Ответ 1
Об этом не консенсус. Некоторым людям нравится использовать их для ясности для выделения переменных класса, и, как заметил один ответчик, избегать конфликтов с именами входящих параметров. Даже в примере с образцом Apple используется смешанное.
Однако я предпочитаю не использовать префикс _
и иметь две сильные причины:
1) Некоторые люди считают, что _
является хорошим индикатором "private". Мое мнение состоит в том, что доступ к локальной переменной класса NO не требуется без setter/getter (свойство), и, следовательно, они ВСЕ являются частными - учитывая, почему они не называют их более удобным для чтения и использования автозаполнения? Любое перекрытие имен от параметров быстро обнаруживается компилятором и избегается более продуманным наименованием параметров (или внутренних переменных).
2) (даже более разумная причина) - если вы используете "refactor" в XCode во внутреннем классе var, который имеет то же имя, что и свойство, используемое для доступа к нему, оператор property и synthesize также будет переименован. Если вы используете refactor для переменной класса с префиксом _
, имя свойства не будет изменено - просто сопоставление синтезируется во внутреннее имя. Я почти никогда не хочу, чтобы имя менялось от свойства до реальной переменной, к которой он предоставляет доступ. Это само по себе заставляет меня никогда не использовать _
как префикс переменной, поскольку возможность смены имен - это самая полезная вещь, которую вы можете сделать для улучшения ясности кода.
Ответ 2
Использование этого синтаксиса - это возможность сделать более понятным, что ivar и свойство - это разные вещи.
Чтобы закодировать внешний класс для класса, нет никакой разницы, поскольку он использует свойство.
Для кода в реализации самого класса он может сделать его более понятным при использовании ivar в сравнении с этим свойством.
Например, скажем, у нас есть свойство ivar/для объекта NSNumber:
@interface MyClass : NSObject {
NSNumber *num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end
@implementation MyClass
@synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
@end
и теперь используя другое имя для ivar и свойства:
@interface MyClass : NSObject {
NSNumber *i_num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end
@implementation MyClass
@synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
@end
Ответ 3
В предыдущих ответах отсутствует история, стоящая за этим. До Objective-C 2.0 свойств не было. Итак, у youd есть объект с такими переменными экземпляра, как это:
@interface MyObject: NSObject {
NSArray *myArray;
}
@end
Но как вы можете получить к ним доступ от других объектов? решение заключалось в создании сеттеров и геттеров. Но чтобы избежать путаницы, они сделают это так:
@interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
@end
_
служит для устранения путаницы между переменной экземпляра _myArray
и методом -myArray
.
Ответ 4
Иногда люди используют mVarName (С++), а в Obj-c стиль выглядит как _varName.
Одна из проблем, которую вы можете иметь, представляет себе, что ваш аргумент функции... set: (int) x - BUT - у вас есть iVar, называемый x... ну, и вы собираетесь заставить компилятор плакать о таких вещах - не упомянуть о его запутывании.
m, _, что помогает показать, какие свойства-члены класса.
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
Ответ 5
Это чисто конвенция. Я полагаю, что это обычное дело, потому что когда вы создаете метод getter, вызывайте так:
[myObject variable]
вы на самом деле вызываете метод, а не напрямую обращаетесь к переменной. перед нами ясно, что вы говорите о переменной. Лично я нахожу этот синтаксис раздражающим и отвлекающим. Я считаю это ненужным, но вы правы, оно появляется здесь и там.
Ответ 6
Я предпочитаю не использовать префикс '_', потому что Apple использует его последовательно. Избегая префикса, я больше уверен, что мои ивары не сталкиваются с Apple, когда я расширяю класс касания cocoa. Поскольку у нас нет доступа к источнику базового класса, это единственный способ узнать, как избежать случайного повторного использования существующих личных иваров.
Во многом как
Имена методов, начинающиеся с символа "_", одного символа подчеркивания, зарезервированы для использования Apple.
Ответ 7
Мое предпочтение, следуя Google, просто добавляет подчеркивание и явно синтезирует (даже если я переопределяю):
@synthesize varName=varName_;
Если я вижу, что конечное подчеркивание вне init...
, dealloc
или аксессора, я знаю что-то подозрительное.