へろへろもへじ

(ブログタイトル募集中)

【Objective-C,iOS】おれおれコーディング規約4ObjC

これまで勉強してきたことをベースにObjective-Cの自分用コーディング規約を作ってみようと思います。
XCodeのバージョンアップによりモダンなスタイルが変わったり、やっぱこれきもいと思った時点で適宜改定していきます。また皆様から「それはないわー」というご意見や、「そこ間違えてるよ」などのご指摘を頂ければ幸いです。



★改訂履歴★
・ver0.1.0 2012-12-01 初版
・ver0.1.1 2012-12-15 「プロトコルの実装時、メソッドには@requiredと@optionalを必ず付与する」を追記

                                                                                                                                  • -

アクセサメソッドは@propertyのみ使用し、@synthesizeを使用しない

XCode4.4から@synthesizeはコンパイラが保管してくれるようになったため、明示的に宣言しなくてもよくなりました。また、@synthesizeで参照するインスタンス変数は"_(アンダーバー) + 変数名"でコンパイラによって保管されます。

before

@interface Hoge ()
{
    @property (strong) NSString *val;
}

@implementation Hoge
{
    @synthesize val = _val;
}

after

@interface Hoge ()
{
    @property (strong) NSString *val;
}

@implementation Hoge
{
    // TODO:コレいらない
    // @synthesize val = _val;
}

クラス内でのみ利用するメンバ(変数、定数、enum、メソッド)は.m(メソッド)ファイルで定義する

Javaを始め、オブジェクト指向言語で一般的なアクセス修飾子の利用がObjCではインスタンス変数のみに限られているため、可読性の観点から一律メソッドファイルにのみ定義するようにします。(@privateなどはインスタンス変数にしか使えないので使いません。)
また、XCode4.4からクラス内で、後に宣言されるメソッドを使用するために、最初に宣言しておく必要がなくなったため、無名カテゴリでのメソッドの宣言も行いません。

プライベートメソッドのメソッド名にprefixとして"$_"をつける

本当は"_(アンダーバー)"だけがいいのですが、"_(アンダーバー)"始まりはApple様がご予約済みだそうで、"_(アンダーバー)"の前に企業名やプロジェクトの英略字をつけてねってことですが、私は"$"にしました。
ソースコードが会社の資源の場合は、企業名orプロジェクト名の英略字が妥当なのでしょうね。

-(void)$_hoge
{
    NSLog(@"hogehoge");
}

数値の定数はenumを使う

Javaでも相当お世話になってますが、これがあるとないとでは可読性が圧倒的に違うと思います。Webや書籍を見ると書き方がXCodeのバージョンによってまちまちですが、以下のフォーマットで書くこととします。

typedef enum Constant : NSUInteger {
    HOGE = 1,
    FOO = 2,
    BAR = 3,
} Constant;

こちらはXCode4.4からの記法ですが、厳密に型チェックがされるそうです。数値以外でも使えるようになる日をお待ちしております。

オブジェクトはリテラルで定義する

こちらもXCode4.4からの記法。

before

NSNumber *num = [NSNumber numberWithInt:100];
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"key1":@"hoge",@"key2":@"foo",@"key3",@"bar",nil];
NSArray* array = [NSArray arrayWithObjects:@"hoge",@"hoge2",nil];

after

NSNumber *num = @100;
NSDictionary *dic = @{@"key1":@"hoge",@"key2":@"foo",@"key3",@"bar"};
NSArray* array = @[@"hoge",@"hoge2"];

コンビニエンスメソッドが用意されているにしても、リテラルで記述したほうが大分シンプルですね。
(ObjCはクラス名もメソッド名も長すぎる・・・)

便利メソッド群を持ったクラス、いわゆるユーティリティ的なクラスは極力作らず、既存クラスに対してカテゴリを使ってメソッドを追加する。

JavaでいうところのDateUtilやらStringUtilやらstaticな便利メソッドを持ったクラス(Javaの皆様にはお馴染みのapache.commonsとかですね)は既存のクラス(NSString,NSDateなど)の責務に収まる範囲ならば作らないということです。

プロトコルの実装時、メソッドには@required(実装強制)と@optional(実装任意)を必ず付与する

@requiredはデフォルトなので、必須ではありませんが、可読性の観点から。(趣味の問題かもしれませんが当方、SQLのORDER句でASCを使う時も省略しないです。)

@protocol Hoge <NSObject>

// 必須じゃないけど付与する
@required
-(void) hogeRequired;
@optional
-(void) hogeOptional;

@end


他、何か思い立ったら継ぎ足していきます。


◆参考URL
https://developer.apple.com/jp/devcenter/ios/library/documentation/CodingGuidelines.pdf
enum-num-num » Big Nerd Ranch Blog