Xcode4.5になってからアプリのスケルトンを作成すると勝手にできていた、以下のカッコつきのinterface宣言。
SomeObject.h
@interface SomeObject : NSObject
@end
SomeObject.m
@interface SomeObject ()
// インターフェース
@end
@implementation SomeObject
// 実装
@end
なぜかSomeObject.m
でもinterfaceの宣言がされている。これが何か意味がわからなかったけれど、クラスエクステンションというものらしい。
クラスエクステンションとは?
クラスエクステンション(Class Extension)とはObjective-Cのカテゴリの一種でエラーを防ぐために使われる。カテゴリにおいては通常Objective-Cのリンカは柔軟性を保証するために、宣言したすべてのカテゴリが実行ファイルに揃っているか確認を行わない。そのためカテゴリに依存しないクラス内でのプライベートメソッドの実装を入れ忘れても、エラーを出さずに実行ファイルが作成されてしまう。
これを防ぐのがクラスエクステンションだ。例にあったSomeObject.mにあるように
SomeObject.m
@interface SomeObject ()
// ここに実装必須なメソッドの宣言を行う
- (void)example:(id)object;
@end
このように宣言すると、コンパイラはコンパイル時に確認を行い、-(void)example:(id)object;
が実装されているかを確認する。
ただしクラスエクステンション自体にはメソッドを隠蔽するような機能はないので、この宣言を行なってプライベートメソッドを宣言したければ、.m
ファイルの方に書く必要がある。
今までプライベートなプロパティやメソッドを書きたければこっちに書けばいいのかぐらいに思っていたが、理屈はどうあれ認識としてはそれで間違いなかったわけだ。