Подтвердить что ты не робот

Соглашение об именах iPhone ivar

Возможный дубликат:
Как подчеркивается символ подчеркивания перед переменной в классе cocoa objective-c?

Я заметил, что во многих справочных материалах я вижу, что много времени переменные называются _variable в файле .h, а затем @synhesize'd в .m файле как

@synthesize variable = _variable;

Почему это сделано? Что мне не хватает?

Спасибо!

4b9b3361

Ответ 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 или аксессора, я знаю что-то подозрительное.