ニューヨーク・タイムズ Objective-Cスタイルガイドからフォークした日本語版になります。問題が見つかったらこちらにあげてください。
このスタイルガイドに述べないことはアップルのガイドラインを参考してください(PDFファイル)。
- ドットノーテーションシンタックス
- スペーシング
- 条件分岐
- エラー処理
- メソッド
- 変数
- 命名
- コメント
- 初期化
- リテラル
- CGRect 関数
- 定数
- 列挙型定数
- ビットマスク
- プライベートプロパティ
- 画像ファイル名
- ブーリアン
- シングルトン
- Xcode プロジェクト
プロパティのアクセスや変更する際に必ずドットノーテーションを使うこと。それ以外の場合は大括弧を使うこと。
良い例:
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
悪い例:
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
- スペース4つでインデントすること。タブキーでインデントしない。Xcodeで設定するように。
- 条件文(
if
/else
/switch
/while
など)のメソッドは初め中括弧を同じ行で書き、終わり中括弧を改行で書くこと。
良い例:
if (user.isHappy) {
// なんとかする
} else {
// 他のをする
}
- メソッドとメソッドは一行を開けること。メソッド内で各処理の間に一行を開けること。
@dynamic
を一行ずつ書くこと。
条件分岐の処理を中括弧の中に書くこと。
良い例:
if (!error) {
return success;
}
悪い例:
if (!error)
return success;
if (!error) return success;
三項演算子をわかりやすくなる場合のみ使うこと。
良い例:
result = a > b ? x : y;
悪い例:
result = a > b ? x = c > d ? c : d : y;
メソッドがエラーの返戻値の参照を返す場合、条件はエラー変数を使わずに、返戻値を使うこと。
良い例:
NSError *error;
if (![self trySomethingWithError:&error]) {
// エラー処理
}
悪い例:
NSError *error;
[self trySomethingWithError:&error];
if (error) {
// エラー処理
}
いくつかのAppleのAPIでは、成功する場合エラー変数にゴミを入れられるので条件がエラー変数がNOになってしまう場合があるので。
メソッドのスコープ(-/+ シンボル)の後にスペースを開けること。
良い例:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
変数名をわかりやすいように命名してください。for()
文以外は一文字の変数名を使わないこと。
米印は変数のものなので変数名に付くように。定数は例外。
良い例:
NSString *text
悪い例:
NSString* text
NSString * text
できればインスタンス変数を使わずにプロパティで宣言すること。また、初期化メソッド(init
, initWithCoder:
, etc…)以外はインスタンス変数を使わないこと。
良い例:
@interface DTTSection: NSObject
@property (nonatomic) NSString *headline;
@end
悪い例:
@interface DTTSection : NSObject {
NSString *headline;
}
メソッド名や変数名が長くてわかりやすいのが良い。
良い例:
UIButton *settingsButton;
良い例:
UIButton *setBut;
定数名をキャメルケースで最初の文字を大文字。
良い例:
static const NSTimeInterval ArticleViewControllerNavigationFadeAnimationDuration = 0.3;
悪い例:
static const NSTimeInterval fadetime = 1.7;
プロパティ名とローカル変数名をキャメルケースで最初の文字を小文字。
LLVMは自動的に@synthesis
してくれるので@synthesis
を書かないこと。
コメントは必要の場合のみ書く。何故か書いたコードを何の処理ができるか書くように。コメントの更新することを忘れずに。必要がなくなったら削除すること。
ブロックコメントをなるべく書かないこと。コードがセルフドキュメンティングしてもらうように。ドキュメンテーション生成用のコメントは例外。
init
メソッドを以下のように書くこと。
- (instancetype)init
{
self = [super init]; // または指定の初期化メソッド
if (self) {
// カスタマイズ初期化処理
}
return self;
}
NSString
、NSDictionary
、NSArray
、と NSNumber
リテラルを使うように。nil
をNSArray
やNSDictionary
リテラルに入れてしまうとクラッシュになるので入れないように。
良い例:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
悪い例:
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018];
CGRect
のx
, y
, width
, と height
の属性をアクセスする際、構造体メンバーをアクセスせずに必ず CGGeometry
関数 を使うこと。Appleの CGGeometry
レファレンスより:
All functions described in this reference that take CGRect data structures as inputs implicitly standardize those rectangles before calculating their results. For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.
良い例:
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
悪い例:
CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
数値やin-line文字列をなるべく定数で宣言するように。あとでリプロダクション時変更しやすいので。定数を#define
ではなくstatic
で宣言するように。
良い例:
static NSString * const AboutViewControllerCompanyName = @"Apple Inc.";
static const CGFloat ImageThumbnailHeight = 50.0;
悪い例:
#define CompanyName @"Apple Inc."
#define thumbnailHeight 2
列挙型定数を宣言する際、enum
ではなく新しい列挙型NS_ENUM()
を使うように。
良い例:
typedef NS_ENUM(NSInteger, AdRequestState) {
AdRequestStateInactive,
AdRequestStateLoading
};
ビットマスクを使う時にNS_OPTIONS
で。
良い例:
typedef NS_OPTIONS(NSUInteger, AdCategory) {
AdCategoryAutos = 1 << 0,
AdCategoryJobs = 1 << 1,
AdCategoryRealState = 1 << 2,
AdCategoryTechnology = 1 << 3
};
プライベートプロパティをインプレメンテーションファイルのクラス拡張に書き、カテゴリ名を空に。
良い例:
@interface DTTAdvertisement ()
@property (nonatomic, strong) GADBannerView *googleAdView;
@property (nonatomic, strong) ADBannerView *iAdView;
@property (nonatomic, strong) UIWebView *adXWebView;
@end
動作名+クラス名あるいはプロパティ名+状態の形で。
良い例:
RefreshBarButtonItem
/RefreshBarButtonItem@2x
やRefreshBarButtonItemSelected
/RefreshBarButtonItemSelected@2x
ArticleNavigationBarWhite
/ArticleNavigationBarWhite@2x
やArticleNavigationBarBlackSelected
/ArticleNavigationBarBlackSelected@2x
.
Imagesフォルダに同じ目的の画像をグループで分ける。
nil
が NO
に分解するのでnil
と比較するの不要。YES
が1だがBOOL
型が8ビットで表されるのでYES
と比較しないこと。
良い例:
if (!someObject) {
}
悪い例:
if (someObject == nil) {
}
良い例:
if (isAwesome)
if (![someObject boolValue])
悪い例:
if ([someObject boolValue] == NO)
if (isAwesome == YES) // 必ずしないこと。
BOOL
プロパティ名が形容詞なら、“is”プレフィックスが不要だがゲッター名を指定するように。
@property (assign, getter=isEditable) BOOL editable;
クラッシュの可能性を避けるため、スレッドセーフパターンでシングルトンを作成するように。
+ (instancetype)sharedInstance
{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
わかりやすいようにXcodeのグループとプロジェクトのフォルダが同じように。型でグループするだけではなく、機能ごとにグループするように。
できれば、targetのBuild Settingsの"Treat Warnings as Errors"をオンにし、多めにアディショナルワーニング をオンにする。特定のワーニングをオフしたい場合、Clang's pragma機能を使ってください。