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' скрывает переменную экземпляра
Существует ли общее или принятое соглашение для борьбы с этими предупреждениями?
Я понимаю, что просто информировать пользователя о том, что они должны указывать экземпляр при обращении к члену класса, но его раздражает.
Ответы
Ответ 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;
}