Objective-C convention to prevent “local declarati

2020-02-02 08:55发布

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 following 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.

标签: objective-c
9条回答
地球回转人心会变
2楼-- · 2020-02-02 09:02

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™.

查看更多
小情绪 Triste *
3楼-- · 2020-02-02 09:06

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.

查看更多
够拽才男人
4楼-- · 2020-02-02 09:08

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;
}
查看更多
Summer. ? 凉城
5楼-- · 2020-02-02 09:08
_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

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2020-02-02 09:09

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
查看更多
闹够了就滚
7楼-- · 2020-02-02 09:10

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.

查看更多
登录 后发表回答