15

インスタンス変数とメソッド引数の命名について、ここの人々はどのような規則に従っていますか? 特にメソッド引数が ivar (インスタンス変数) の設定に使用される場合は?

m_C++ では、ivarのプレフィックスをよく使用していました。C# では、単純にthis.for ivar を使用してあいまいさを解消するという規則に従いました。それ以来、C++ でも同等のものを採用しました ( this->)。

Objective C でいくつかのことを試しましたが、満足できるものはありませんでした。

誰かが本当に良いことを提案しない限り、私は妥協しなければならないという事実に辞任しています (ただし、the引数に接頭辞を使用させないでください!)。 ObjC をしばらく使用している方。

これを投稿する前に十分な注意を払い、いくつかの優れたリソースを見つけました。

彼らは私にいくつかのアイデアを与えてくれますが、私はまだ他の人が何をしているかを聞きたいと思っています.

[編集] 明確にするために: 具体的には、私が探しているメソッド引数から ivar を区別する方法です-それがプレフィックスまたは他の手法によるものであるかどうか.

[編集 2] すべての応答とディスカッション ポイントに感謝します。これを閉じるつもりはありませんが、受け入れられた回答へのコメントで示したように、 init args の前に を付けるという規則を使用しました(そして、とにかく行っていた のthesetter args )。new私自身美学に熱心ではありませんが、これが力の最良のバランスのようです.

4

5 に答える 5

17

お気づきのように、Cocoa スタイルではtheValue、引数名がインスタンス変数と競合する場合のように、メソッドの引数名を使用します。ただし、これが Objective-C 2.0 スタイルのコードに現れることはあまりないはずです。(通常は) インスタンス変数に直接アクセスしてはならないという前提があります。これは主に、そうすることで Cocoa の Key-Value Observing 機構が回避されるためです。むしろ、getter/setter メソッドを介してプロパティにアクセスし、変更することが期待されます。Objective-C 2.0 では、これらのプロパティとゲッター/セッターを自動的に宣言するのは簡単な@synthesizeので、それらを使用しない理由はほとんどありません。実際、64 ビット システムでは、ランタイムが自動的にインスタンス変数を作成するため、インスタンス変数を宣言する必要がなくなり、変数を使用する必要が減ります。

インスタンス変数に直接アクセスする必要があるのは、-initand-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 を直接使用する必要がある理由は、ゲッター/セッターが完全に初期化されたインスタンスに依存する副作用を持ち、オブジェクトの状態が完全に初期化されている場所で-init危険になる可能性があるためです。-deallocそれ以外の場合はすべて、self.ivar(または[self ivar]and [self setIvar:newValue]) を使用する必要があります。

以外のメソッド-initWithXXには名前の競合がないように思われます。もしそうなら、そのパラメーターを持たないように、またはクラスがインスタンス変数を持たないようにリファクタリングするべきではありませんか?

これにより-initWithXX、引数と ivar の間で競合が頻繁に発生するメソッドのみが残ります。この場合、Cocoa スタイルに本当に耐えられない場合は、言及したアプローチのいずれかを使用できます。でのプレフィックスは_機能し、比較的一般的です (@synthesizeこの場合、'd セッターとゲッターは自動的に正しいことを行うと思いますが_ivar、バッキングとして明示的に設定する必要がある場合があります)。

于 2009-02-15T05:19:50.107 に答える
2

すべての既知の Objective-C スタイルガイドを完成させるには、ここに Google バージョンがあります。彼らがすることは、メンバー varname の後にアンダースコアを追加することです。たとえばBOOL isActive_;
したがって、選択を行い、それに固執してください。また、自分のアプリでは "_" プレフィックスを好みます。

于 2009-02-16T07:05:03.297 に答える
1

これがAppleのやり方です。

于 2009-02-14T23:37:00.290 に答える
1

Obj-Cは、他の多くの言語ほど厳密に「スタイル」を定義していません。これは良いことでも悪いことでもありますが、ほとんどの場合、自分で良いコーディングスタイルを見つける必要があります。

また、selfを介してObj-Cの変数にアクセスすることもできます。したがって、インスタンス変数テストがある場合は、self-> testを介してアクセスできます。これは合法であり、常に機能します。ただし、ほとんどのObj-Cプログラマーの目には美しくありません。これは、オブジェクトが実際には単なる構造体であり(より正確には、オブジェクトrefは構造体へのポインターである)、インスタンス変数は実際には構造体メンバーであるという「秘密」を与えます。これが本当に秘密であるというわけではありませんが、Obj-Cプログラマーは、コードでこの事実を「隠す」ことを好むようです。

名前にアンダースコア「_」を使用することは非常に悪い考えです。ここで誰かがAppleがコードにアンダースコアを予約していると指摘しましたが、実際にはGCCはすでにシンボル名にアンダースコアを予約しています。より正確には、すでにANSI-C標準では、2つのアンダースコアまたは1つのアンダースコアと大文字で始まる変数は、コンパイラの内部使用のために予約されているとされています。したがって、1つのアンダースコアを使用することは理論的には有効ですが、誤って名前を大文字で始めると無効になります。

これまでに試したのは、名前の代わりに接頭辞my、myNameを使用し、名前の代わりに接頭辞self、selfNameを使用することでした。最初はどちらも奇妙に見えますが、巨大なコードではそれほど悪くはありません。少なくともすぐに「違う」と目が離せません。また、名前の代わりにiName(または名前の代わりにiname)という単一の「i」を試しましたが、その解決策にはあまり満足していませんでした。

ただし、メソッドパラメータについて考えるのに時間を無駄にすることはありませんでした。それは本当に重要ではないからです。これらは、定数として宣言されていない限り、他の変数と同じように変数です。呼び出し元に影響を与えないため、メソッド内の他の目的に再利用することもできます。例えば

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

そのコードには問題はありません。名前が意味をなす限り、なぜそのために2番目のスタック変数を宣言する必要があるのでしょうか(forループで画像を番号で反復処理しない場合、名前はもちろん意味がありません。その場合は、そのための別の変数-コンパイラは実際には両方のためにスタック上に1つのintのみを予約する場合があります)。

于 2009-12-09T15:02:42.900 に答える
1

Apple が作成したサンプル コードでは、通常、"_" プレフィックスを使用しています。mFooorを使っているものも見たと思います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規則は、Apple (iPhone) のサンプル コードで使用されています。

[self bar]いずれにせよ、インスタンス変数は通常は使用されないため、"_" 接頭辞が煩わしい場合は問題ありませself.barん。

于 2009-02-15T06:19:44.113 に答える