Objective-CというかiOSのアプリ開発における自分流コーディング規約のまとめ。SDKのヘッダ、Xcodeが自動生成したコード、メジャーなオープンソースライブラリなどを参考にしました。本家や大御所に合わせておくほうが無難だと思います。もちろんここに述べるものは絶対的な基準ではありません。個人的なものなので、あくまで参考ということでお願いします。

※ 間のspaceの入れ方も決まり事としています。

ポインタ

NSString *string;
  • NSString* string派だったが、上記の方が一般的なようなので矯正した

クラス、プロトコル

PSImageLoader
PSImageLoaderDelegate
  • 大文字2文字のプレフィックスで始める
  • プレフィックスはアプリケーション、ライブラリ固有のものにする
  • 例)アプリ名Passionz -> PS

メンバ変数、プロパティ

メンバ変数はすべてプロパティで定義する。

@property (nonatomic) uint64 cursor;
@property (strong, nonatomic) NSString *description;
@property (weak, nonatomic) id<PSImageLoaderDelegate> delegate;
  • @property{space}(nonatomic){space}uint64{space}cursorのようにspaceを入れる
  • メンバ変数同様、オブジェクトの場合strongかweakは明記する
  • プロパティとして定義したものはデフォルトでは、アンダースコア+プロパティ名でメンバ変数として参照できるので、メンバ変数はいちいち定義しない。定義した方がわかりやすいかもしれないが、タイポで食い違うとバグの元になりかねない。自分はそちらを懸念する

公開するメンバ変数はヘッダ側に書く。

@interface Hoge

@property (nonatomic) uint64 cursor;
@property (strong, nonatomic) NSString *description;
@property (weak, nonatomic, readonly) IBOutlet UILabel *titleLabel;

@end

注意すべきはIBOutlet + readonlyなプロパティはソース側で@synthesizeの定義が必要になる。

@synthesize titleLabel = _titleLabel;

非公開(private)なメンバ変数はソース側に書く。

@interface Hoge ()

@property (nonatomic) uint32 count;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

かつてはプライベート変数はプロパティではなく以下のように宣言するようにしてた。

@implementation PSImageLoader {
    PSImageLoaderState _state;
}

しかし、

  • あまり一般的でなさそう
  • 公開・非公開で宣言の記述が変わるのが面倒
  • ブロック関数だとプロパティの方がwarning回避できたり勝手が良い

の理由でやめました。

メソッド

- (id)initWithName:(NSString *)name;
- (BOOL)start;
  • -{space}(id)initWithName:のようにspaceを入れる

シングルトン

+ (id)sharedImageLoader;
+ (id)defaultImageLoader;
  • アプリケーション内で1つしかオブジェクトを生成しない場合、shared{プレフィックス抜きのクラス名}
  • 通常はデフォルトのオブジェクトを使う場合、default{プレフィックス抜きのクラス名}。この場合は状況に応じてalloc/initでインスタンス生成する場合もある

ローカル変数、引数

int index = 0;
NSString *companyName = @"stack3";
  • メンバ変数と重複しないように先頭にアンダースコアをつけないこと

定数、enum

#define PSErrorDomain @"net.stack3.passionz"
UIKIT_EXTERN const int PSImageLoaderTimeout;
// ソース側(*.m)で 
// const int PSImageLoaderTimeout = 3;
// のように定義する

typedef enum {
    PSImageLoaderStateNormal,
    PSImageLoaderStateLoading,
    PSImageLoaderStateCompleted
} PSImageLoaderState;
  • 先頭にkはつけないことにした。SDKでkがつくものは比較的古いソースコードという印象を受けたため
  • 大文字+アンダースコア区切りはSDKでは、C言語レベルのdefineという印象なので避けることにした
  • クラス名と重複する恐れがあるが、そうなる場合は名前自体に問題があるのだと考えることにした

ポインタ定数

NSString *const string = @"string";

以下のようにするとポインタのアドレスもポインタ上の値も書き換え不可能になる。より安全だが多くの場所で引数として渡すときにwarningになるので実質使えない。

const NSString *const string = @"string";

インデント

  • space4文字、tabは使わない

括弧の位置

- (id)fullName
{
    return [NSString stringWithFormat:@"%@ %@", _firstname, _lastname];
}
  • メソッドの実装は最初の括弧は一段下げる
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        // Do something.
    }
}
  • 基本それ以外は空白を入れて横に書く
  • メソッドの実装だけ一段下げる必要性をあまり感じないが、Xcodeが自動生成するフォーマットに合わせている。そこだけ他と異なると嫌なので・・・