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

Objective-C соглашение, предотвращающее "локальное объявление скрывает переменную экземпляра" предупреждение

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

-(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' скрывает переменную экземпляра
  • Локальная декларация 'сравненияValue' скрывает переменную экземпляра

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

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

4b9b3361

Ответ 1

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

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

    return self;
}

Ответ 2

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

В соглашении указано, что вы префикс private variables с символом подчеркивания (_varName) и public (например, свойства) с просто именем.

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

Пример:

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

Ответ 3

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

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

    // do stuff

    return self;
}

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

Ответ 4

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

Ответ 5

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

-(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;
}

Вы можете узнать о GCP pragma here и получить предупреждающий код предупреждения в Log Navigator (Command + 7), выбрать верхняя строчка, раскройте журнал (кнопка "=" справа) и прокрутите вниз, и там ваш код предупреждения находится в квадратных скобках, например, [-Wshadow-ivar]


Edit

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

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow-ivar"
// your code
#pragma clang diagnostic pop

Ответ 6

_varName = varName;

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

Ответ 7

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

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

Дополнительная информация в этом сообщении в блоге


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

@synthesize variableName = _variableName;

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

Ответ 8

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

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

Ответ 9

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

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

Второй метод:, если вы хотите использовать глобальную переменную, тогда вызовите 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;
}