カテゴリーでインスタンス変数的なものを追加する

objective-cのカテゴリーって便利ですね。

最近はついついなんでもカテゴリーで実装しちゃいますが(ダメ!)、この機能には弱点があります。
それは、インスタンス変数が追加できないことです。
(C#の拡張メソッドもそうですよね。)

まぁ継承して使えばなにも問題は無いのですが、継承するほどの事でもないな、って時はこんな方法で解決できます。

ソースを見たらすぐに理解できると思います。

#import <objc/runtime.h>

//宣言
@interface UIView (Title)

@property (nonatomic) NSString* title;

@end

//実装
@implementation UIView (Title)

static NSString* title_key = @"title-key";

-(void)setTitle:(NSString*) title
{
    objc_setAssociatedObject(self, title_key, title, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSString*) title
{
    return objc_getAssociatedObject(self, title_key);
}

@end


objc_setAssociatedObject、objc_getAssociatedObjectを使うと保存出来る事が分かるのではないでしょうか。

ちょっと補足すると、これは関連参照という機能を使っており、オブジェクトとオブジェクトとを特定のキーで紐付けすることで保持する機能です。
この例ではインスタンス変数なのでselfに対してtitleを関連付けて保存しているのです。

また、上記ソースを見て、「プロパティの破棄してないやんけ!(激怒)」と思いますよね。
これも関連参照の便利な所なのですが、対象のオブジェクトが破棄された時に自動的に関連付けたオブジェクトも破棄してくれます。カシコイですね。

コメントを残す

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