ReactiveCocoaでタイマー処理

最近一部で話題(と勝手に思っている)の ReactiveCocoa

NSTimerでも問題ないことですが、場合によっては別にメソッド作ったり、セレクター指定が面倒なこともあるので、以下のような簡単なタイマー処理をReactiveCocoaで書いてみます。

- (void)setUpTimer {
    [NSTimer scheduledTimerWithTimeInterval:5.0
                                     target:self
                                   selector:@selector(someMethod:)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)someMethod:(NSTimer *)timer {
    NSLog(@"%@", timer);
}

これが次のようになります。

- (void)setUpTimer {
    [[RACSignal interval:5.0] subscribeNext:^(NSDate *date) {
        NSLog(@"%@", date);
    }];
}

簡単ですね!

キャンセルしたい場合は、-subscribeNextの戻り値のRACDisposableを-disposeすることは推奨されていないようなので、

@property (nonatomic, strong) RACSubject *cancelSubject;

- (void)setUpTimer {
    [[[RACSignal interval:5.0] takeUntil:self.cancelSubject] subscribeNext:^(NSDate *date) {
        NSLog(@"%@", date);
    }];
}

- (void)cancelTimer {
    [self.cancelSubject sendNext:[RACUnit defaultUnit]];
}

こんな感じにすれば良さそうです。takeUntil:の引数に指定したRACSignalが値を発行する(sendNext:)か完了する(sendCompleted)と、レシーバーのsignalが終了するようになります。

ちなみに +[RACSignal interval:] メソッドは内部で dispatch_source を使用していますねー。