Effective Objective-C 2.0 第3章(インターフェイスとAPI設計)メモ
項目15 名前空間の衝突を避けるプレフィックス名を使う
Appleが2文字のプレフィックスを使う権利を保有してるので、
- クラス名とかデリゲートメソッドに3文字以上のプレフィックスをつけようず
クラスだけでなく、クラス実装ファイル内で使っている純粋C関数やグローバル変数にも気をつける。
項目16 イニシャライザを用意せよ
指定イニシャライザ(designated initializer): スーパークラスの指定イニシャライザをsuperを通して呼び出し、自分のクラスで必要な初期化を最も詳細に行う初期化メソッド。initWithCoder:とかが指定イニシャライザになり得る。
副次的イニシャライザ(secondary initializer): 指定イニシャライザをselfを通して呼び出してるイニシャライザ。
項目17 descriptionメソッドの実装
- descriptionを実装するんだよ。
- デバッグ用にはdebugDescriptionがあるんだよ。
- NSDictionaryのdescription使うと見やすいらしいっすよ。
項目18 できるだけイミュータブルなオブジェクトを使う
- プロパティはヘッダでreadonlyにして、クラスエクステンションでreadwriteにするといいよ
- プロパティとしてミュータブルなコレクションを公開するのではなく、オブジェクトが管理するコレクションを書き換えるためのメソッドを提供しよう
※コレクションを返したい場合は、(コピーコストが少ないなら)copyしたものを返すようにする。
その際、戻り値をイントロスペクションでミュータブルかどうか調べて、内容を書き換えるようなまねはしない方が良い。
項目19 明快で首尾一貫した名前を使う
標準APIを参考にすればいいんじゃね的な内容。
項目20 非公開メソッド名にはプレフィックスを付ける
筆者はプライベートメソッドのプレフィクスにprivateのpにアンダースコアを付けたp_を使っている。
うーん、publicもpなんだよなぁ... まあプライベートメソッドの方にしか付けないから区別できるけどね。
項目21 Objective-Cエラーモデルを理解する
- 例外は、App.を狩猟させるべき致命的エラーのとき限り使う
ARCは例外セーフでない。コンパイルオプション-fobjc-arc-exceptionsを指定しておけば、例外セーフコードを生成してくれるが、例外が投げられていないときにも実行しなければならないコードが生成される。MRCでも例外を投げる前にリソースを解放させるように気をつけなければならない。
NSErrorを使う場合は↓のような感じ。domain, code等は、グローバル定数のNString*const, typedef NS_ENUM(NSUInteger, xxx)を使えば良い。
NSError *error = nil; BOOL ret = [obj doSomething:&error]; if (error/* or ret */) { /* handle error */ }
- (BOOL)doSomething:(NSError**)error { //ARCのときは(NSError*__autoreleasing*)に書き換えられる。 //do something if (/* there was an error */) { if (error) { //if error == nil, return only result (success or failure). //NSStirng *domain, NSInteger code, NSDictionary *info *error = [NSError errorWithDomain:domain code:code userInf:info]; } return NO; } return YES; }
項目22 NSCopyingプロトコルを理解する
- ミュータブル版、イミュータブル版があるオブジェクトのコピー対応には、NSCopying, NSMutableCopyingプロトコルを使う。
allocWithZoneとイニシャライザを使って以下を実装。
- (id)copyWithZone:(NSZone*)zone; //NSCopying protocol - (id)mutableCopyWithZone:(NSZone*)zone; //NSMutableCopying protocol
- シャローコピーするかディープコピーをするかを決め、可能な限りシャローコピーを採用するようにする
Foundationのすべてのコレクションクラスは、デフォルトでシャローコピー。