开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜