4

Objective-C (ただし長期の C/++) プログラマーは初めてなので、変数の命名規則に関するアドバイス/推奨事項を探しています。

私の個人的な好みは、関数内を明確にし、関数パラメーターのシャドウイングを防ぐために、インスタンス変数にプレフィックスを使用することです。ただし、私は接頭辞を除外するプロパティのファンです (プロパティ名にも接頭辞を付けない限り、うまく機能せず、ばかげているように見えます)。同様に、「self.variable」規約を使用することもできますが、すべてをプロパティにする場合に限られます。

以下のコードを考えると、インスタンス/関数変数の好みの命名スタイルは何ですか? 気にしないのであれば、関数パラメーターのシャドーイングをどのように処理しますか?

@interface GridItem : NSObject
{
    CGRect _rect;
    ...  
}
@end

-(void) initFromRect:(CGRect)rect
{
    _rect = rect;
    ...
}

乾杯!

4

10 に答える 10

15

IBOutletほとんどの Cocoa プロジェクトは、非インスタンス変数のプレフィックスとしてアンダーバーを使用し、インスタンス変数にはプレフィックスを使用しませんIBOutlet

インスタンス変数にアンダーバーを使用しない理由はIBOutlet、nib ファイルがロードされたときに、接続されたアウトレットのセッター メソッドがあれば、そのセッターが呼び出されるからです。 ただし、このメカニズムはKey-Value コーディングを使用しないため、名前の前にアンダーバーが付く IBOutlet ( eg _myField ) は、セッターがアウトレット ( eg )とまったく同じように命名されていない限り、設定されません set_myField:

また、次のようなプロパティを使用することは、インスタンス変数にアクセスすることと同じself.myPropではないことに注意してください。のようなブラケット表記を使用した場合と同様に、プロパティを使用するとメッセージが送信されます[self myProp]。すべてのプロパティが行うことは、ゲッターとセッターの両方を 1 行で指定するための簡潔な構文を提供し、それらの実装を合成できるようにすることです。メッセージディスパッチメカニズムを実際に短絡するわけではありません。インスタンス変数に直接アクセスしたいが、その前にプレフィックスを付けたい場合は、ポインターとしてself扱う必要があります。これは実際には C スタイルのフィールド アクセスです。selfself->myProp

最後に、Cocoa のコードを書くときは決してハンガリー語表記を使用しないでください。また、"f" や "m_" などの他の接頭辞は避けてください。他の Cocoa 開発者から疑いの目で見られる可能性があります。

一般に、 Apple Developer Connectionの Cocoaドキュメントのコーディング ガイドラインのアドバイスに従ってください。そうすれば、他の開発者があなたのコードを理解して理解できるようになります。また、あなたのコードは、ランタイム イントロスペクションを使用するすべての Cocoa 機能でうまく機能します。

私の慣例を使用すると、ウィンドウコントローラークラスは次のようになります。

// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    IBOutlet NSTextField *nameField;
    IBOutlet NSTextField *titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;

@end

// EmployeeWindowController.m
#import "EmployeeWindowController.h"

@implementation EmployeeWindowController

@synthesize employee = _employee;

- (id)initWithEmployee:(Employee *)employee {
    if (self = [super initWithWindowNibName:@"Employee"]) {
        _employee = [employee retain];
    }
    return self;
}

- (void)dealloc {
    [_employee release];

    [super dealloc];
}

- (void)windowDidLoad {
    // populates the window's controls, not necessary if using bindings
    [nameField setStringValue:self.employee.name];
    [titleField setStringValue:self.employee.title];
}

@end

Employeeを直接参照するインスタンス変数を-initand-deallocメソッドで使用し、プロパティを他のメソッドで使用していることがわかります。これは通常、プロパティの良いパターンです。初期化子、-dealloc、およびプロパティの getter と setter で、プロパティの基になるインスタンス変数に触れるだけです。

于 2008-08-15T05:32:40.293 に答える
8

IBOutlets にもアンダースコアを使用していることは認めますが、アンダースコアの ivar プレフィックスに関する Chris Hanson のアドバイスに従います。ただし、@ mmalcの提案IBOutletに従って、最近、宣言を@property行に移動し始めました。利点は、すべての ivar にアンダースコアが付き、標準の KVC セッターが呼び出されることです (つまり)。また、Interface Builder ではアウトレット名にアンダースコアがありません。setNameField:

@interface EmployeeWindowController : NSWindowController {
@private
    // model object this window is presenting
    Employee *_employee;

    // outlets connected to views in the window
    NSTextField *_nameField;
    NSTextField *_titleField;
}

- (id)initWithEmployee:(Employee *)employee;

@property(readwrite, retain) Employee *employee;
@property(nonatomic, retain) IBOutlet NSTextField *nameField;
@property(nonatomic, retain) IBOutlet NSTextField *titleField;

@end
于 2008-11-10T16:31:11.157 に答える
3

ivar でアンダーバー プレフィックスを使用しても、プロパティにはアンダーバー以外の名前を使用できます。合成アクセサーの場合は、次のようにします。

@synthesize foo = _foo;

これにより、_foo ivar を使用して foo プロパティを合成するようにコンパイラに指示されます。

独自のアクセサーを作成する場合は、実装でアンダーバー ivar を使用し、アンダーバー以外のメソッド名を保持します。

于 2008-09-15T16:20:12.153 に答える
2

個人的には、Cocoa の命名規則に従い、関数と変数にはキャメル ケーシングを使用し、オブジェクト名には大文字のキャメル ケーシングを使用します (もちろん先頭の NS は使用しません)。

型の接頭辞を付けると、コードを書いていない人にとってはコードがより不透明になることがわかります (誰もが常に異なる接頭辞を使用するため)。また、最新の IDE では、何かの型を理解することはそれほど難しくありません。

于 2008-08-13T20:38:36.397 に答える
2

プロパティの導入により、クラス インスタンス変数の前に「_」を付ける必要がなくなりました。クラスの外部にアクセスする変数は、プロパティを介してアクセスするか、クラスのカスタム メソッドを使用して値に影響を与える必要があるという簡単なルール (ヘッダー ファイルに記述) を設定できます。これは、名前の前に「_」が付いている名前よりもずっときれいに思えます。また、値の変更方法を制御できるように、値を適切にカプセル化します。

于 2008-09-15T06:00:54.000 に答える
1

私のスタイルはハイブリッドで、実際には PowerPlant 時代からの名残りです。

私が使用する最も便利なプレフィックスは、関数/メソッド パラメーターの "in" と "out" です。これにより、パラメーターが何のためにあるのかが一目でわかり、メソッド パラメーターとインスタンス変数の間の競合を防ぐのに役立ちます (パラメーター「テーブル」が同じ名前のインスタンス変数と競合するのを何回見たことか)。例えば:

- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;

次に、インスタンス変数とプロパティ名にそのままの名前を使用します。

次に、ローカル変数の接頭辞として「the」を使用します: theTable、theURL など。これも、ローカル変数とインスタンス変数を区別するのに役立ちます。

次に、PowerPlant のスタイリングに続いて、いくつかの他のプレフィックスを使用します。定数には k、列挙には E、グローバルには g、静的には s です。

私はこのスタイルを12年ほど使用しています。

于 2008-10-01T14:46:47.170 に答える
1

Andrew: 実際、インスタンス変数のプレフィックスをまったく使用しない Cocoa 開発者はたくさんいます。また、これは Smalltalk の世界でも非常に一般的です (実際、Smalltalk では、インスタンス変数にプレフィックスを使用することはほとんど前代未聞だと思います)。

インスタンス変数の接頭辞は、Java に持ち込まれ、C# に持ち込まれた C++ 主義のように常に私を驚かせてきました。Objective-C の世界は C++ の世界とほぼ平行しており、Java と C# の世界はその後継者であるため、さまざまな開発者の間で見られる「文化的な」違いを説明できます。

于 2008-08-15T05:36:36.043 に答える
1

C と C++ は両方とも、実装で使用するために特定のアンダースコア プレフィックスを予約しているため、識別子のプレフィックスとしてアンダースコアを使用するのは好きではありません。

「self.variable」の使用は見苦しいと思います。

一般的に、私はインスタンス変数に装飾のない識別子 (つまり、接頭辞も接尾辞もありません) を使用します。クラスが複雑すぎてインスタンス変数を覚えられない場合は、問題が発生します。あなたの例では、インスタンス変数の名前として「rect」を使用し、パラメーター名として「newRect」または「aRect」を使用します。

于 2008-08-13T20:36:32.877 に答える
1

ここで述べたことに加えて、Key Value Observing 準拠の命名に関する Cocoa のドキュメントを必ずお読みください。このパターンに厳密に従うことは、長期的には非常に役立ちます。

于 2008-11-17T21:21:30.377 に答える
1

ivar にアンダースコア プレフィックスを使用するのは好きです@synthesizeが、すべての重複があるため、行を書くのは嫌いです (あまりDRYではありません)。これを行い、コードの重複を減らすためにマクロを作成しました。したがって、代わりに:

@synthesize employee = _employee;

私はこれを書きます:

ddsynthesize(employee);

これは、トークンの貼り付けを使用して右側にアンダースコアを追加する単純なマクロです。

#define ddsynthesize(_X_) @synthesize _X_ = _##_X_

唯一の欠点は、Xcode のリファクタリング ツールを混乱させ、リファクタリングによってプロパティの名前を変更すると、名前が変更されないことです。

于 2008-11-10T16:37:38.727 に答える