如何使用ReactiveCocoa移除观察者?

6
如何在某些事件后停止接收新名称?
[RACObserve(self, username) subscribeNext:^(NSString *newName) {
    if ([newName isEqualToString:@"SomeString"])
    {
       //Do not observe any more
    }
}];

抱歉问一个显而易见的问题,但我找不到答案。

2个回答

11
你可以使用从'subscribeNext'返回的RACDisposable对象的方法'dispose'。
__block RACDisposable *handler = [RACObserve(self, username) subscribeNext:^(NSString *newName) {
    if ([newName isEqualToString:@"SomeString"]) {
        //Do not observe any more
        [handler dispose]
    }
}];

谢谢!这正是我想要看到的。 - serj
如果在这行代码之前,self.username 等于 'SomeString',那么处理程序不会被释放,对吗? - KudoCC

9

在ReactiveCocoa中,需要以一种不同的方式思考问题:你不想“移除”观察者,而是想创建一个信号,在发生某些事情时完成。

您可以使用takeUntilBlock:来派生一个信号,该信号将在一定时间后停止发送值:

[[RACObserve(self, username) takeUntilBlock:^(NSString *name) {
    return [name isEqualToString:@"something"];
}] subscribeNext:^(NSString *name) {
    NSLog(@"%@", name);
}];

但这不会为字符串@"something"发送下一个,只有它之前的名称。如果需要这样做,可以将其附加到末尾:

NSString *sentinel = @"something";
[[[RACObserve(self, username) takeUntilBlock:^(NSString *name) {
    return [name isEqualToString:sentinel];
}] concat:[RACSignal return:sentinel]] subscribeNext:^(NSString *name) {
    NSLog(@"%@", name);
}];

虽然不是很优雅,但你可以创建一个takeUntilBlockInclusive助手函数来实现这个行为,并将丑陋的细节隐藏在其中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接