Reactivecocoa: What's the most elegant way to merge a dynamic set of signals?

Created on 24 Jun 2015  ·  3Comments  ·  Source: ReactiveCocoa/ReactiveCocoa

I'm finding myself using the following little class quite a bit to present a changing set of signals as one merged signal. Is there a more elegant way to accomplish the same thing?

@interface SignalSet : NSObject
@property (nonatomic, readonly) RACSignal *mergedSignal;
- (void)addSignal:(RACSignal *)signal;
@end

@implementation SignalSet

- (instancetype)init {
    self = [super init];

    if (self) {
        _signals = [NSSet new];

        _mergedSignal = [[RACObserve(self, signals) map:^RACSignal *(NSSet *signals) {
            return [RACSignal merge:signals];
        }] switchToLatest];
    }

    return self;
}

- (void)addSignal:(RACSignal *)signal {
    self.signals = [self.signals setByAddingObject:signal];

    [signal finally:^{
        // Remove the signal from the set to release it
        self.signals = [[NSSet alloc] initWithArray:[[self.signals rac_sequence] ignore:signal].array];
    }];
}

@end
question

All 3 comments

Sure, you can accomplish roughly the same interface with a RACSubject:

RACSubject *signalSet = [RACSubject subject];
RACSignal *mergedSignals = [signalSet flatten:0];

// Add a signal
[signalSet sendNext:someSignal];

Better yet, depending on your requirements, you may be able to avoid RACSubject:

RACSignal *mergedSignals = [RACSignal never];

// Add a signal
mergedSignals = [mergedSignals merge:someSignal];

By the way, -finally: doesn't add side effects to an existing signal. Rather, it returns a new signal with side effects. The following does nothing because the returned signal is discarded and never subscribed to:

[signal finally:^{
    // Remove the signal from the set to release it
    self.signals = [[NSSet alloc] initWithArray:[[self.signals rac_sequence] ignore:signal].array];
}];

Thanks! I like the second form.

This helped me in 2019. Thanks a lot @brow

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lxian picture lxian  ·  6Comments

gabro picture gabro  ·  5Comments

mdiep picture mdiep  ·  5Comments

simonxcheng picture simonxcheng  ·  6Comments

v-silin picture v-silin  ·  4Comments