4

我想在iOS中使用Reactive Cocoa来实现倒数计时器。计时器应运行X秒,并在每秒钟内做一些事情。我无法弄清的部分是我可以通过取消超时时间反应可可中的可取消超时

RACSubscribable *oneSecGenerator = [RACSubscribable interval:1.0]; 
RACDisposable *timer = [[oneSecGenerator take:5] subscribeNext:^(id x) { 
    NSLog(@"Tick"); 
}]; 
+0

为什么不是普通的'NSTimer'?你可以' - 无效'它... – 2012-11-25 21:43:40

+1

我想利用反应行为。我知道如何用NSTimer做这件事,但这是一个产生较少错误代码的实验。命令式编程难以处理大型状态空间的复杂性。这是响应式编程可以帮助的地方。 – allprog

+0

在ReactiveCocoa的当前版本中,一旦获取了指定数量的值,'take'操作将自动终止'oneSecGenerator'信号。 – erikprice

回答

4

我想,我找到了解决办法。诀窍是将取消信号合并到刻度信号中,然后取X个样本。最后的订户将在每次打勾信号时收到下一个事件,并且当'take'完成时完成。取消可以通过在取消定时器上发送错误来实现。

__block RACSubject *cancelTimer = [RACSubject subject]; 
RACSubscribable *tickWithCancel = [[RACSubscribable interval:1.0] merge:cancelTimer]; 
RACSubscribable *timeoutFiveSec = [tickWithCancel take:5]; 

[timeoutFiveSec subscribeNext:^(id x) { 
    NSLog(@"Tick"); 
} error:^(NSError *error) { 
    NSLog(@"Cancelled"); 
} completed:^{ 
    NSLog(@"Completed"); 
    [alert dismissWithClickedButtonIndex:-1 animated:YES]; 
}]; 

要激活取消,必须执行以下操作。

[cancelTimer sendError:nil]; // nil or NSError 
+0

哪个版本的ReactiveCocoa在运行?我的版本不接受'''RACSubscribable merge'''的参数。 – EightyEight

+0

我使用可可豆荚,这是在版本0.8。正如我在新版本中看到的,RACSubscribable已更名为RACSignal。这可能对你有所不同。我使用这种重载' - (RACSubscribable *)合并:(RACSubscribable *)subscribable;' – allprog

+1

我没有最新的;我从github抓起了我的。有'''Cancellable''' subscribables,这可能值得研究。我需要类似的东西来取消一系列异步网络操作。 – EightyEight

3

还有其确实exactly what you want:继电器事件从一个流至另一个产生值的TakeUntil operator

+0

TakeUntil不适用于我的情况,因为它没有提供区分最终案例的方法。超时是否发生或取消是否被解雇很重要。 TakeUntil只需在取消发送下一个时完成流。至少这是它在Reactive Cocoa中的实现方式。 – allprog

+0

哦,我不知道你必须在取消时出错。在那种情况下,TakeUntil确实不适合你。 – thSoft