代码之家  ›  专栏  ›  技术社区  ›  philsquared

目标C中的实例变量/方法参数命名

  •  15
  • philsquared  · 技术社区  · 17 年前

    这里的人们在命名实例变量和方法参数时遵循哪些约定?特别是当使用方法参数设置IVAR(实例变量)时?

    在C++中我用过 m_ this. 对于ivars。此后我也采用了C++中的等价物。 this-> ).

    在目标C中,我尝试了一些事情,但没有一件看起来令人满意。

    除非有人提出一些很好的建议,否则我不得不妥协(但请不要让我使用 the args的前缀!),所以我很想听听大多数人怎么说——特别是那些已经使用ObjC一段时间的人。

    在发布这篇文章之前,我做了一些尽职调查,并找到了一些好的资源:

    他们给了我一些想法,但我仍然渴望听到其他人在做什么。

    [编辑]

    [编辑2] 感谢所有的回复和讨论要点。我不是要结束这篇文章,但我只想说,正如我在对已接受答案的评论中所指出的那样,我遵循了在init args前面加前缀的惯例 这个 new ,反正我也在做)。这似乎是力量的最佳平衡——即使我自己并不热衷于美学。

    5 回复  |  直到 17 年前
        1
  •  17
  •   Barry Wark    17 年前

    正如您所注意到的,Cocoa风格是使用方法参数名称,如 theValue 如果参数名称与实例变量冲突。然而,在Objective-C2.0风格的代码中,不应该多次出现这种情况。假设您不应该(通常)直接访问实例变量。这主要是因为这样做绕过了可可中的关键价值观察机制。相反,我们的期望是通过getter/setter方法访问和修改属性。在Objective-C2.0中,很容易声明这些属性并自动 @synthesize

    您应该直接访问实例变量的唯一时间是在 -init 和 -dealloc

    @interface MyObject : NSObject 
    {
      id ivar;
    }
    
    @property (retain,readwrite) id ivar; //or whatever retain/copy/assign and read/readwrite makes sense
    @end
    
    @implementation MyObject
    @synthesize ivar;
    
    - (id)initWithIvar:(id)theIvar {
      if(self = [super init]) {
        ivar = theIvar;
      }
    
      return self;
    }
    
    - (void)dealloc {
      [ivar release];
    }
    

    在这些情况下应该直接使用ivar的原因是,getter/setter可能会产生依赖于完全初始化实例的副作用,从而使它们在应用中变得危险 -初始化 和 其中对象的状态已完全初始化。在所有其他情况下,您应该使用 self.ivar (或 [self ivar] 和 [self setIvar:newValue] ).

    看来,除了 -initWithXX 不应该有命名冲突。如果有,是否应该重构它们,使其不具有该参数或类不具有实例变量?

    这只剩下最后一个问题了 方法,您经常会发现参数和IVAR之间存在冲突。在这种情况下,如果你真的无法忍受可可风格,你可以使用你提到的任何方法。前缀为 _ 有效且相对普遍(我相信 @综合 _ivar 作为后盾)。

        2
  •  2
  •   kompozer    17 年前

    here 是谷歌版。他们所做的是在成员varname后面添加下划线。例如 BOOL isActive_; .

        3
  •  1
  •   wfarr    17 年前

    这是怎么做的 Apple does it

        4
  •  1
  •   sebnow    17 年前

    苹果公司生产的示例代码通常使用一个“u”前缀。我想我也看到了一些 mFoo 或 m_foo . 有些人根本不用前缀,只使用普通名称,但这在以后会让人困惑。通常在定义方法参数时,命名约定是使用“a”、“an”、“the”或“new”前缀。例如:

    @interface Foo : NSObject {
        id _bar;
    }
    @property (nonatomic, retain) id bar;
    
    - (id) initWithBar:(id)aBar;
    
    @end
    
    @implementation Foo
    @synthesize bar = _bar;
    
    - (id) initWithBar:(id)aBar {
        self = [super init];
        if(self != nil) {
            _bar = aBar;
        }
        return self;
    }
    
    @end
    

    我发现这个惯例很有效。我过去不在乎前缀,但这有时会让人困惑。使用前缀清楚地表明它是一个实例变量。这个 @synthesize bar = _bar

    实例变量通常不会被使用,所以如果你觉得“\u1”前缀很烦人,那也没关系,因为你会使用 [self bar] self.bar 如果你对这类事情感兴趣)无论如何。

        5
  •  1
  •   Mecki    16 年前

    Obj-C不像其他语言那样严格地定义“风格”,这可能是一件好事,也可能是一件坏事,但这意味着大部分时间你都需要自己去寻找一种好的编码风格。

    您还可以通过self访问Obj-C中的变量。因此,如果您有一个实例变量测试,您可以通过self->测试,这是合法的,并且永远有效。然而,在大多数Obj-C程序员眼中,它并不美丽。它泄露了一个“秘密”,即对象实际上只是结构(更准确地说,对象引用是指向结构的指针),实例变量实际上是结构成员。这并不是真正的秘密,但Obj-C程序员似乎更喜欢在他们的代码中“隐藏”这一事实。

    到目前为止,我试着用前缀my,myName代替name,用前缀self,selfName代替name;起初看起来都很奇怪,但在一段庞大的代码中看起来并不太糟糕。至少马上就被认为是“与众不同”。我还尝试了一个“我”,用iName代替name(或者用iName代替name),但我对这个解决方案不是很满意。

    不过,我从不浪费时间考虑方法参数。因为这并不重要。这些变量和其他变量一样,除非它们被声明为常量。它们甚至可以在方法中用于其他目的,因为它对调用方没有影响。例如。

    - (NSImage *)loadImage:(int)imageNumber
    {
      NSImage * res;
    
      // Some code that assigns a value to res
      // ...  
    
      // Re-use imageNumber for a different purpose
      for (imageNumber = 0; ...; ...) {
         // Some code
      }
    
      return res;
    }
    

    推荐文章