在Objective-C中消除参数名称与实例变量名称的歧义的良好实践

时间:2012-01-05 18:08:12

标签: iphone objective-c ios cocoa

我在Objective-C中遇到了一个相当常见的场景,我将一个变量传递给一个init方法,然后将它分配给一个同名的实例变量。但是我没有找到一种方法来扩展变量的范围,以澄清哪个是来自message参数的值,哪个是实例变量。

说我有一些课程如下:

@interface MyObject
{
    NSString *value;
}
- (id)initWithValue:(NSString *)value;
@end

在我的实现中,我希望我的init方法看起来像这样:

- (id)initWithValue:(NSString *)value
{
    self = [super init];
    if(self) {
        self.value = value;  // This will not work with instance variables
    }
}

我知道三种解决方案:

  1. 创建一个允许调用self.value
  2. 的属性
  3. 重命名我的实例变量,例如_value
  4. 重命名我的init参数变量,例如initValueargValue
  5. 我对这些解决方案都不满意。添加属性要么使该属性在接口上公开可用,要么如果我使用扩展,则将其隐藏在继承者中。我也不喜欢为变量设置不同的名称或使用下划线,这可能来自于其他语言(如Java和C#)的开发。

    有没有办法消除消息参数中的实例变量的歧义?如果没有,Cocoa中是否有编码指南来解决这个问题?我喜欢在适当的时候遵循风格指南。

    更新

    在考虑如何在C中执行此操作后,我想出了self->value的解决方案。这有效,但它会产生一个编译器警告:本地声明'value'隐藏了实例变量。所以这不是一个令人满意的解决方案,因为我有一个零警告目标。

3 个答案:

答案 0 :(得分:4)

对于setter(以及扩展名初始值设定项),我认为约定是在参数名前加上new

- (void)setCrunk:(Crunk *)newCrunk;
- (id)initWithCrunk:(Crunk *)newCrunk;

一般来说,我认为我见过的最常见的形式是调用参数theCrunk,但Apple seems to recommend aCrunk

答案 1 :(得分:3)

将名称更改为“inValue”不是一个好主意?你在这里有什么 - 你的“解决方案”很复杂,特别是对于Obj-C 2的访问器等。由于self.value和inValue是不同的东西,它们需要不同的名称。

请注意,您可以使用

-(void)method1:(NSString*)value; 
标题

中的

-(void)method1:(NSString*)inValue; 
<。>在.m文件中。

答案 2 :(得分:2)

如果只使用1,编译器会给你一个警告。

你可以结合1&amp; 2使用:

@synthesize value = _value;

如果你想从继承者隐藏你的变量,你可以声明一个空的命名类别并在那里声明你的属性。

对于3,您可以使用aValue作为参数。