在完成之前不要触发RACSignal副作用

时间:2015-10-23 10:21:39

标签: ios iphone reactive-cocoa

我正在尝试创建将在第一次订阅时触发副作用的信号,并为任何进一步的订阅重播事件。一旦信号发送完成或错误,我想重新触发下一次订阅的副作用。我想出了这个解决方案,但我想知道是否有更优雅的方法来解决这个问题。

@interface ViewController ()
@property (nonatomic, assign) NSUInteger counter;
@property (nonatomic, strong) RACSignal *defferedIncrement;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [[self defferedIncrement] subscribeNext:^(id x) {
        NSLog(@"Count: %@", x);
    }];

    [[self defferedIncrement] subscribeNext:^(id x) {
        NSLog(@"Count: %@", x);
    }];
}

- (IBAction)buttonDidTap:(id)sender {
    [[self defferedIncrement] subscribeNext:^(id x) {
        NSLog(@"Count: %@", x);
    }];
}

- (RACSignal *)realIncrement
{
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            RACDisposable *disposable = [RACDisposable new];
            if (disposable.disposed) { return disposable; }

            ++self.counter;

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{    
                [subscriber sendNext:@(self.counter)];
                [subscriber sendCompleted];
            });

            return disposable;
    }];
}

- (RACSignal *)defferedIncrement
{
    if (!_defferedIncrement) {
        _defferedIncrement = [[RACSignal defer:^RACSignal *{
            return [[self realIncrement] finally:^{
                _defferedIncrement = nil;
            }];
        }] replayLazily];
    }

    return _defferedIncrement;
}

@end

0 个答案:

没有答案