こちらの記事(Objective-Cでドット繋ぎでメソッドチェインを行う)を読んでいて、まだまだ理解が浅いなーと思ったので、自分で色々書きながらメモ。
(そしてARCの恩恵をとても受けているんだなーということを実感した)
サンプルコード
まず、該当記事から少しコードを参考にさせて頂いて、以下のように簡単な例を書いてみました。
(Xcode上ではなく、コマンドラインからコンパイルする感じです)
main.m
#import <Foundation/Foundation.h>
@interface NSArray (functional)
@property (readonly) NSArray *(^filter)(BOOL (^)(id));
@end
@implementation
- (NSArray *(^)(BOOL (^)(id)))filter
{
// ARC環境下でない場合は、明示的にコピーを返さないとエラーになる
return [^(BOOL (^block)(id)) {
NSMutableArray *arr = [NSMutableArray array];
for (id obj in self) {
if (block(obj)) {
[arr addObject:obj];
}
}
return arr;
} copy];
}
@end
int main()
{
NSArray *arr = @[@1, @2, @3, @4, @5];
NSArray *filtered = arr.filter(^BOOL (id num) {
return [num intValue] > 3;
});
NSLog(@"%@", filtered); // => 4, 5
return 0;
}
実行
$ gcc -o sample main.m -framework Foundation
$ ./sample
$ 2014-05-30 11:52:33.450 sample[48557:507] (
4,
5
)
少し分かりやすく変更
上記はblockの型をそのまま書いているのでとても分かりづらいですね。
なので、typedef
を使って少しだけ分かりやすくすると以下の感じ。
main.m
typedef NSArray *(^array_filter)(BOOL (^)(id));
// @property (readonly) NSArray *(^filter)(BOOL (^)(id));
@property (readonly) array_filter filter;
// - (NSArray *(^)(BOOL (^)(id)))filter
- (array_filter)filter
{
// 省略
}
typedef
を使うと少し分かりやすいですね。
また、参考にした記事を見てもらうと分かりますが、NSarray
を拡張しているので、戻り値のNSArray
に対してさらにプロパティアクセスができます。
つまり、メソッドチェーンが行える、ということですね。
実際に使うシーンというのはあるのか分かりませんが、blockの仕組みとともに覚えておいて損はないんじゃないかなーと思いました。