最终永远不会使用已完成的replaySubject调用ReactiveCocoa。这是预期的行为吗?

时间:2014-04-14 11:28:15

标签: reactive-cocoa

这是预期的行为吗?

RACSubject *subject = [RACReplaySubject replaySubjectWithCapacity:1];
[subject sendCompleted];
[subject finally:^{
    NSLog(@"never called");
}];
[subject subscribeCompleted:^{
    NSLog(@"called");
}];

如果是这样,我如何finally喜欢阻止?我需要这样吗?

void (^block)() = ^ {
    NSLog(@"like finally!");
};
[subject subscribeError:^(NSError *error) {
    block();
} completed:^{
    block();
}];

编辑:对于那些误解finally喜欢我的人,the document for renamed doFinished in RAC 3.0可以帮助您理解,而不是the 2.X document

1 个答案:

答案 0 :(得分:2)

这实际上与信号已经完成无关。考虑一下:

RACSubject *subject = [RACSubject subject];
[subject finally:^{
    NSLog(@"never called");
}];
[subject subscribeCompleted:^{
    NSLog(@"called");
}];
[subject sendCompleted];

仍未打电话!为什么?因为finally:会返回一个新信号;它不会修改现有信号。只要向其订户之一发送completederror,新信号就会执行这些副作用。如果它没有任何订阅者,那么这些副作用将永远不会发生。现在让我们订阅finally:返回的信号:

RACSubject *subject = [RACReplaySubject replaySubjectWithCapacity:1];
[subject sendCompleted];
[[subject finally:^{
    NSLog(@"called now!");
}] subscribeCompleted:^{
    NSLog(@"called");
}];

这有效,但可能不是你真正想要的。 finally:不会将副作用注入信号,它会为每个信号订阅注入副作用。以下是:

RACSubject *subject = [RACReplaySubject replaySubjectWithCapacity:1];
[subject sendCompleted];
RACSignal *signalWithFinally = [subject finally:^{
    NSLog(@"finally block");
}];
[signalWithFinally subscribeCompleted:^{
    NSLog(@"first subscriber completed");
}];
[signalWithFinally subscribeCompleted:^{
    NSLog(@"second subscriber completed");
}];

将执行finally:阻止两次,这可能不是您想要的。 subscribeError:completed:可能是您用例的更好选择。