سؤال

I'm using ReactiveCocoa to compose complex signal of the following structure:

RACSignal* data1FromNetwork = ...;
RACSignal* data1FromNetworkHub = [data1FromNetwork replayLazily];
RACSignal* derivedData = [data1FromNetworkHub flattenMap:...];
RACSignal* data2FromNetwork = ...;
RACSignal* result = [RACSignal combineLatest:@[data1FromNetworkHub, derivedData, data2FromNetwork] reduce:...];

Signal data1FromNetwork is implemented as a network call, but has multiple subscribers - derivedData and in combineLatest:reduce:. So to avoid duplicating network calls, I use replayLazily to create a hub signal, that can be used for multiple subscriptions.

When I cancel result, all subscriptions to the hub signal get disposed, but the subscription between the hub signal and data1FromNetwork itself remains. So data1FromNetwork does not get cancelled. Underlying network request completes, RACReplaySubject created inside replayLazily gets notified, and data process stops at this point without any visible effect.

This is acceptable, but can be done better - I'd like all network activity to be cancelled as well. Can this be achieved using built-in RAC operators?

هل كانت مفيدة؟

المحلول

It might be represented like that using -[RACMulticastConnection autoconnect]:

RACSignal* data1FromNetwork = ...;

RACSignal* data1FromNetworkHub = [[data1FromNetwork publish] autoconnect];
// Or below if you want replaying behavior.
// RACSignal* data1FromNetworkHub = [[data1FromNetwork multicast:RACReplaySubject.subject] autoconnect];

RACSignal* derivedData = [data1FromNetworkHub flattenMap:...];
RACSignal* data2FromNetwork = ...;
RACSignal* result = [RACSignal combineLatest:@[data1FromNetworkHub, derivedData, data2FromNetwork] reduce:...];

When the signal returned by -autoconnect got to have no subscribers, the underlying signal (data1FromNetwork in this case) would be disposed.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top