Соглашение Objective C, чтобы предотвратить "локальное объявление скрывает переменную экземпляра" предупреждение - PullRequest
25 голосов
/ 30 марта 2010

Я использую следующий код ...

-(id) initWithVariableName:(NSString*)variableName withComparisonValue:(NSString*)comparisonValue {

    // super init
    self = [super init];
    if (!self) return nil;

    // set instance variables
    self.mustExist = NO;
    self.reverseCondition = NO;
    self.regularExpression = NO;
    self.variableName = variableName; // generates warning
    self.comparisonValue = comparisonValue; // generates warning

    return self;
}

, который выдал следующие два предупреждения ...

  • Локальное объявление 'variableName' скрывает переменную экземпляра
  • Локальное объявление 'CompareValue' скрывает переменную экземпляра

Существует ли общепринятая или общепринятая конвенция для работы с этими предупреждениями?

Я понимаю, что просто сообщить пользователю, что он должен указывать экземпляр при обращении к члену класса, но это раздражает.

Ответы [ 9 ]

32 голосов
/ 23 сентября 2011

Я вижу, что это довольно старый вопрос с принятым ответом, но у меня есть лучшее решение и его кодовое соглашение.

Соглашение гласит, что префиксные переменные ставятся перед подчеркиванием (_varName), а публичные (как свойства) - только именем.

При этом вы можете просто вызывать одно и то же имя переменной в своих функциях.

Пример:

ExampleClass.h

@interface ExampleClass : NSObject
{
    NSString *_varName; //this is not required if you create a property
}

@property (nonatomic, retain) NSString *varName;

- (void)someMethodWithVarName:(NSString *)varName;

@end

ExampleClass.m

#import "ExampleClass.h"

@implementation ExampleClass

@synthesize varName = _varName; //if you don't declare the _varName in the header file, Objective-C does it for you.

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

- (void)someMethodWithVarName:(NSString *)varName
{
    _varName = varName; //just for example purpose
}

@end
28 голосов
/ 30 марта 2010

К сожалению, нет "хорошего" способа предотвратить эту ошибку. Обычный шаблон - использовать слегка глупое имя параметра, например

-(id) initWithVariableName:(NSString*)theVariableName 
       withComparisonValue:(NSString*)theComparisonValue {
    self.variableName = theVariableName;
    self.comparisonValue = theComparisonValue;

    return self;
}
4 голосов
/ 30 марта 2010

Если ваш метод действительно инициализатор, не забудьте выполнить self = [super init];.

- (id) initWith...
{
    self = [super init];
    if (!self) return nil;

    // do stuff

    return self;
}

Я никогда не сталкивался лично с ситуацией, когда self изменился на nil или другое значение, но это идиома Objective-C Initialiser Idiom ™.

3 голосов
/ 17 апреля 2013

Хотя это старый вопрос, но все же у меня есть хорошее решение для подавления предупреждения в коде

-(id) initWithVariableName:(NSString*)variableName withComparisonValue:(NSString*)comparisonValue {

    // super init
    self = [super init];
    if (!self) return nil;

    // set instance variables
    self.mustExist = NO;
    self.reverseCondition = NO;
    self.regularExpression = NO;


    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wshadow-ivar"
    self.variableName = variableName; // generates warning
    self.comparisonValue = comparisonValue; // generates warning
    #pragma GCC diagnostic pop



    return self;
}

Вы можете узнать о прагме GCC здесь и чтобы получить код предупреждения о предупреждении, перейдите в Навигатор Журналов (Команда + 7), выберите самую верхнюю сборку, разверните журнал (кнопка '=' справа) и прокрутите вниз, и там ваш код предупреждения находится в квадратных скобках, как это [-Wshadow-ivar]


Редактировать

Для лязга вы можете использовать

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow-ivar"
// your code
#pragma clang diagnostic pop
3 голосов
/ 30 марта 2010

Либо дайте локальному более описательное имя (например, initialVariableName), либо присвойте переменным экземпляра другое обозначение (например, myClass_variableName). Я предпочитаю последнее в большинстве случаев, потому что оно привлекает внимание, когда я использую внутренние классы, а не надлежащий интерфейс.

2 голосов
/ 18 апреля 2013

Это не проблема вообще в современном Objective-C. В современном Objective-C свойства автоматически синтезируются, и соответствующие им переменные экземпляра получают префикс _.

Итак, при автоматическом синтезе ваши свойства будут создавать переменные экземпляра _variableName и _comparisonValue. В этом случае не происходит затенение.

Больше информации в этом сообщении в блоге


Если вам абсолютно необходимо вручную синтезировать ваши свойства, переименуйте синтезированный ivar следующим образом

@synthesize variableName = _variableName;

В общем случае переименуйте аргументы вашего метода.

2 голосов
/ 18 апреля 2013
_varName = varName;

Вы можете использовать только это, но без @synthesize - когда вы хотите использовать эту переменную, вы просто пишете _*variable name*, и это устраняет ошибку

1 голос
/ 30 марта 2010

Обычно вы должны ставить переменные экземпляра перед символом подчеркивания (например, _variableName), чтобы избежать таких предупреждений компилятора.

В противном случае просто слегка измените имена в сигнатуре вашего метода, нет жестко определенного соглашения об именах.

0 голосов
/ 28 июня 2017

Если вы используете локальное имя переменной экземпляра, такое же, как имя глобальной переменной экземпляра, то появляется это предупреждение.

Первый метод: Для игнорирования этого предупреждения необходимо изменить имя переменной локального экземпляра или изменить имя глобальной переменной экземпляра.

Второй метод: если вы хотите использовать глобальную переменную, тогда вызовите как self->variableName

-(id) initWithVariableName:(NSString*)variableName withComparisonValue:(NSString*)comparisonValue {

    // super init
    self = [super init];
    if (!self) return nil;

    // set instance variables
    self->variableName = variableName; //point to global variableName
    self->comparisonValue = comparisonValue; //point to global comparisonValue

    return self;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...