Objective-Cでカテゴリーを実装する際に hogehoge.ex.foo() のようにプロパティを噛ましたい


はじめに

こちらは先日投稿した SwiftでExtensionを実装する際に hogehoge.ex.foo() のようにプロパティを噛ましたい - Qiita の Objective-C 版になります.

Objective-Cを使ってる(た)人なら,タイトルは [[hogehoge ex] foo][hogehoge.ex foo] なのでは?だと誤りと思いますが,最近Objective-Cを使うならメインをSwiftにしてだろうと思って,このようにしてます.Objective-Cだけを使う人は置き換えて見て下さい.

カテゴリーを作る

UITableViewにカテゴリーを生やす例で紹介します.以下のクラス名などは任意で適当に付けています.

カテゴリー用の変数を作る

まずカテゴリー用のクラス MyExtension を作成します.このクラスから生成した変数から,カテゴリーを作りたいインスタンスにアクセスします.

MyExtension.h
@interface MyExtension : NSObject
@end
MyExtension.m
@interface MyExtension ()

@property (nonatomic, weak) UITableView *tableView;
- (instancetype)initWithTableView:(UITableView *)tableview;

@end

@implementation MyExtension

- (instancetype)initWithTableView:(UITableView *)tableview{
    self = [super init];
    if (self) {
        self.tableView = tableview;
    }
    return self;
}
@end

カテゴリー用の変数を生やす

作成したカテゴリー用のクラスを,カテゴリーを作成したいクラスに適用します.associate機能を使って,カテゴリーで変数を追加します.

UITableView+.h
@interface UITableView (extension)

@property (nonatomic, retain) MyExtension* ex;

@end 
UITableView+.m
#import <objc/runtime.h>
static void *MyExtensionKey = &MyExtensionKey;

@implementation UITableView (extension)

- (MyExtension*)ex{
    MyExtension *temp = objc_getAssociatedObject(self, MyExtensionKey);
    if (temp == nil){
        temp = [[TableViewExtension alloc] initWithTableView:self];
        [self setEx:temp];
    }
    return temp;
}

- (void)setEx:(MyExtension *)ex{
    objc_setAssociatedObject(self,
                             MyExtensionKey,
                             ex,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

カテゴリーのメソッドを追加する

最初に作成した MyExtension にメソッドを追加しています.

MyExtension.h
@interface MyExtension : NSObject

- (void)foo;

@end
MyExtension.m
@implementation MyExtension

- (void)foo{
   UITableView *tableView = self.tableView;
   // 処理
}
@end

まとめ

今更 Objective-C で新規開発する場面は少なくなったと思いますが,これで Objective-C でもカテゴリーで追加するメソッドを変数を噛ませて使用できます(あまり使用シーンはないと思いますが).私は最近SwiftからObjective-Cの機能を使いたくて作ってみました( こちら ).この記事は実際のソースではどうなっているか気になる方はどうぞ.