Objective-C convention to prevent "local declaration hides instance variable" warning
I am using the following code ...
-(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;
}
which generated the follo开发者_运维问答wing two warnings ...
- Local declaration of 'variableName' hides instance variable
- Local declaration of 'comparisonValue' hides instance variable
Is there a common or accepted convention for dealing with these warnings?
I understand that it is simply to inform the user that they should specify an instance when referring to the class member, but its annoying.
I see this is a fairly old question with a accepted answer but I have a better solution and its code convention.
The convention states that you prefix private variables with a underscore (_varName) and public (like properties) with just the name.
With this you just can call the same variable name in your functions.
Example:
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
Unfortunately, no there's no "good" way to prevent this error. The common pattern is to use a slightly stupid parameter name like
-(id) initWithVariableName:(NSString*)theVariableName
withComparisonValue:(NSString*)theComparisonValue {
self.variableName = theVariableName;
self.comparisonValue = theComparisonValue;
return self;
}
If your method truly is an initialiser, don't forget to do your self = [super init];
.
- (id) initWith...
{
self = [super init];
if (!self) return nil;
// do stuff
return self;
}
I have never personally encountered a situation where self
has changed to nil
or another value, but it's the Objective-C Initialiser Idiom™.
Either give the local a more descriptive name (e.g. initialVariableName) or give instance variables a different notation (e.g. myClass_variableName). I prefer the latter in most cases because it calls attention to when I'm using class internals rather than the proper interface.
This is not a problem at all in the modern Objective-C. In the modern Objective-C, properties are automatically synthesized and their corresponding instance variables get a _
prefix.
So, with auto-synthesis your properties would create instance variables _variableName
and _comparisonValue
. No shadowing occurs in this case.
More info in this blog post
If you absolutely need to manually synthesize your properties, rename the sinthesized ivar like this
@synthesize variableName = _variableName;
In general case, rename your method arguments.
_varName = varName;
You can use just this but without the @synthesize
- whenever you want to use that variable you just write _*variable name*
and it eliminates the error
Though it's old question but still I've a good solution to suppress warning in code
-(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;
}
You can learn about GCC pragma here and to get the warning code of a warning go to the Log Navigator (Command+7), select the topmost build, expand the log (the '=' button on the right), and scroll to the bottom and there your warning code is within square brackets like this [-Wshadow-ivar]
Edit
For clang you can use
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow-ivar"
// your code
#pragma clang diagnostic pop
You should generally prefix instance variables with something like an underscore (e.g. _variableName) to avoid compiler warnings like this.
Otherwise just slightly change the names in your method signature, there is no hard defined naming convention.
If you are using local instance variable name same as global instance variable name then this warning occur.
First Methode: For ignoring this warning use have to change local instance variable name or else change the global instance variable name.
Second Methode: if you want to use global variable then call as 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;
}
精彩评论