我正在使用以下代码......
-(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;
}
产生以下两个警告......
处理这些警告是否有共同或公认的惯例?
我知道只是告诉用户他们应该在引用类成员时指定一个实例,但它很烦人。
答案 0 :(得分:32)
我认为这是一个相当古老的问题,并且已经接受了答案,但我有更好的解决方案和代码约定。
约定规定,您只需使用下划线(_varName)和公共(如属性)为私有变量添加名称。
这样你就可以在函数中调用相同的变量名。
示例:
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
答案 1 :(得分:28)
不幸的是,没有“好”方法来防止此错误。常见的模式是使用一个稍微愚蠢的参数名称,如
-(id) initWithVariableName:(NSString*)theVariableName
withComparisonValue:(NSString*)theComparisonValue {
self.variableName = theVariableName;
self.comparisonValue = theComparisonValue;
return self;
}
答案 2 :(得分:4)
如果您的方法确实是初始化者,请不要忘记执行self = [super init];
。
- (id) initWith...
{
self = [super init];
if (!self) return nil;
// do stuff
return self;
}
我从未亲身遇到self
已更改为nil
或其他值的情况,但它是Objective-C Initialiser Idiom™。
答案 3 :(得分:3)
为本地提供更具描述性的名称(例如initialVariableName)或为实例变量提供不同的表示法 (例如myClass_variableName)。在大多数情况下,我更喜欢后者,因为当我使用类内部而不是正确的接口时,它会引起注意。
答案 4 :(得分:3)
虽然这是一个老问题,但我仍然是一个很好的解决方案来抑制代码中的警告
-(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;
}
您可以了解GCC pragma here并获取警告的警告代码进入Log Navigator(Command + 7),选择最顶层的构建,展开日志(右侧的'='按钮) ,并滚动到底部,警告代码在方括号内,如[-Wshadow-ivar]
修改强>
对于clang,您可以使用
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow-ivar"
// your code
#pragma clang diagnostic pop
答案 5 :(得分:2)
_varName = varName;
您可以使用此但不使用@synthesize
- 只要您想使用该变量,只需编写_*variable name*
即可消除错误
答案 6 :(得分:2)
在现代Objective-C中,这根本不是问题。在现代Objective-C中,属性会自动合成,其对应的实例变量将获得_
前缀。
因此,通过自动合成,您的属性将创建实例变量_variableName
和_comparisonValue
。在这种情况下不会出现阴影。
如果您绝对需要手动合成属性,请像这样重命名sinthesized ivar
@synthesize variableName = _variableName;
一般情况下,重命名方法参数。
答案 7 :(得分:1)
通常应该使用下划线(例如_variableName)为实例变量添加前缀,以避免像这样的编译器警告。
否则只需稍微更改方法签名中的名称,就没有硬定义的命名约定。
答案 8 :(得分:0)
如果您使用的本地实例变量名称与全局实例变量名称相同,则会出现此警告。
First Methode:要忽略此警告,请使用更改本地实例变量名称,否则更改全局实例变量名称。
第二个Methode:如果您想使用全局变量,请调用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;
}