yaakaito.org

Objective-CでRoleやってみる

Objective-C

こんにちは、うきょーです! Objective-C書いててふと、Role使いたいなー出来たっけーと、思ったのでやってみた。

怪しいところもあるので、あんまり参考にならないかもですよと言っておく。

最終的にデータと振る舞いを合体させる

ってのができればいいと思うんだけど、Objective-Cならカテゴリで書いておけばよくね?と思ったり思わなかったり。 けどちょっと違うよねーってことで、今回はそういうのはやめとく。

で、実装としてはNSProxy使えばそれっぽいものは割と簡単に出来た。

ObjCRoleSample

1
2
3
4
@interface Book : NSObject
@property (nonatomic, strong) NSString *title;
@property (nonatomic) NSUInteger price;
@end

こういうモデルに対して、

1
2
3
4
5
6
7
8
@implementation BookPurchase

- (void)purchase
{
    Book *this = (Book *)self.target;
    NSLog(@"Purchased! %@ %u", this.title, this.price);
}
@end

こんな感じの振る舞いを、

1
2
3
4
5
6
7
Book *book = [[Book alloc] init];
book.title = @"hoge";
book.price = 420;

Book<BookPurchase> *extended = [book roleExtended:BookPurchase.class];

[extended purchase];

こう合成できるようにしてみた。

Book<BookPurchase>が気に入らないと人は、ちょっと微妙な感じがするんだけど、Bookの定義の方に書いちゃえば省略はできる。

実装としては基本的にはNSProxyで自分にメッセージ送れなかったら流すようにしたものをベースクラスにしてあげて、protocolを使ってこんな感じでロールを定義する

1
2
3
4
5
6
7
@protocol BookPurchase <NSObject>
@optional
- (void)purchase;
@end

@interface BookPurchase : OCRole <BookPurchase>
@end

こうやるとBookPurchaseロールとBookモデルで同じメッセージが送れるような(正確にはXCodeでコンパイル出来るような)感じになる。 見た目はあんまりよくない。し、あんまり実用的でもないような感じがする。マクロとかで書きやすくしてあげるとちょっとは変わるかなー。

宣伝:2/23に東京でiOSカンファレンスを開催します!

「conferenceWithDevelopers」というタイトルです。

公式サイト

チケットをゲットはこちらから

無料です!

豪華スピーカーでお送りしますので、みなさん是非ご参加ください!LT発表者も募集してますよ!