【Objective-c】カテゴリーで、既存クラスを分割・拡張

iPhone

カテゴリーによるクラスの分割

カテゴリーを使えば、クラスが持つメソッドを、カテゴリごとに分類することができます。
ということは、大きいクラスの実装を、複数のファイルに分割できるということですね。

 // Japaneseクラスの宣言
 @interface Japanese : NSObject
 {
    // インスタンス変数
    NSString* title;
 }
 - (NSString*)title;
 - (void)setTitle:(NSString*)title;
 @end
 
 // Japaneseクラスの Katakana カテゴリ
 @interface Japanese ( Katakana )
 - (void)writeToFile:(NSString*)path;
 - (void)readFromFile:(NSString*)path;
 @end

@interface クラス名 ( カテゴリー名 ) と書きます。
カテゴリー側で独自のインスタンスを宣言する必要はありません。

他クラスからは、

 Japanese* ja = [[Japanese alloc] init];
 ja.title = @"test";
 [ja readFromFile: @"test"];
 [ja writeToFile: @"test"];

というように使えます。

既存クラスの拡張

実行中、動的に既存のクラスにメソッドを追加していくことができるのですが、カテゴリーにはこの機能があります。
カテゴリーによって分割されたクラスは、各々別のオブジェクトとしてコンパイルされます。
その後、これらが実行時に読み込まれ、カテゴリーで宣言されているメソッドがクラスに追加されていきます。
自分でつくったクラスだけでなく、Cocoaが提供するクラスに対しても可能です。

例えば、NSString。

 // NSStringの新たなカテゴリの宣言
 @interface NSString (TrimNewLine)
 - (BOOL)hasNewLineCharacters;
 - (NSString*)stringByTrimmingNewLineCharacters;
 @end
 
 @implementation NSString (TrimNewLine)
 - (BOOL)hasNewLineCharacters
 {
    // 改行コードが含まれていたら、YESを返す
    ……
 }
 - (NSString*)stringByTrimmingNewLineCharacters
 {
    // 改行コードを除去した文字列を返す
    ……
 }
 @end

これで、以下のように追加したメソッドを簡単に利用することができます。

 NSString* string = @"string\nです。";
 if ([string hasNewLineCharacters])
 {
     NSLog(@"%@",[string stringByTrimmingNewLineCharacters]);
 }

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です