Is there a ReactiveCocoa method like publish, but that forwards the latest value to new subscribers?

StackOverflow https://stackoverflow.com/questions/21765057

  •  11-10-2022
  •  | 
  •  

Domanda

I often use ReactiveCocoa to track the latest value of some variable, like the text in a text field. Sometimes these latest values are actually themselves computed, in a way that multiple subscriptions causes the computations to happen multiple times. Often it would be significantly more efficient to merge these computations.

What I would like to use is RACSignal* sharedComputationLatest = complicatedLatestValue.publish.autoconnect, but then when new subscribers subscribe to the shared computation signal they are not told the latest value.

Is there a variant of publish, some sort of publishLatest, that already exists and does what I need? If not, does it already exist and have a name in .Net's Rx?

Update: It turns out that autoconnect has slightly different semantics than I thought, namely that if the number of subscribers goes to zero and then back up there is no re-connection. I needed the re-connection bit, so I implemented my own method (in an answer below).

È stato utile?

Soluzione

Sounds like you want -replayLast.

Altri suggerimenti

Here's a custom implementation (note: not thread safe):

-(RACSignal*) publishLatestAutoreconnect {
    __block int32_t subscriberCount = 0;
    __block RACDisposable* subscription = nil;
    __block RACReplaySubject* publishSubject = nil;

    return [RACSignal createSignal:^RACDisposable*(id<RACSubscriber> subscriber) {
        __block RACDisposable* _subscriberDisposable = nil;

        // auto[re]connect if we had no subscribers
        subscriberCount++;
        if (subscriberCount == 1) {
            publishSubject = [RACReplaySubject replaySubjectWithCapacity:1];
            subscription = [self subscribe:publishSubject];
        }

        // forward to subscriber
        _subscriberDisposable = [publishSubject subscribe:subscriber];

        return [RACDisposable disposableWithBlock:^{
            // stop forwarding to subscriber
            [_subscriberDisposable dispose];

            // disconnect if we now have no subscribers
            subscriberCount--;
            if (subscriberCount == 0) {
                [subscription dispose];
                subscription = nil;
                publishSubject = nil;
            }
        }];
    }];
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top