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
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