我发现自己经常使用以下小类来将一组不断变化的信号呈现为一个合并信号。 有没有更优雅的方法来完成同样的事情?
<strong i="6">@interface</strong> SignalSet : NSObject
<strong i="7">@property</strong> (nonatomic, readonly) RACSignal *mergedSignal;
- (void)addSignal:(RACSignal *)signal;
<strong i="8">@end</strong>
<strong i="9">@implementation</strong> 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];
}];
}
<strong i="10">@end</strong>
当然,您可以使用RACSubject
完成大致相同的界面:
RACSubject *signalSet = [RACSubject subject];
RACSignal *mergedSignals = [signalSet flatten:0];
// Add a signal
[signalSet sendNext:someSignal];
更好的是,根据您的要求,您可以避免RACSubject
:
RACSignal *mergedSignals = [RACSignal never];
// Add a signal
mergedSignals = [mergedSignals merge:someSignal];
顺便说一句, -finally:
不会对现有信号添加副作用。 相反,它返回一个带有副作用的新信号。 以下什么都不做,因为返回的信号被丢弃并且从未订阅:
[signal finally:^{
// Remove the signal from the set to release it
self.signals = [[NSSet alloc] initWithArray:[[self.signals rac_sequence] ignore:signal].array];
}];
谢谢! 我喜欢第二种形式。
这在 2019 年帮助了我。非常感谢@brow