ios - 仅对新订阅者进行信号重试

标签 ios reactive-cocoa

我正在使用缓存重放信号的典型模式:

- (RACSignal *)resultSignal {
    if (!_resultSignal) {
        _resultSignal = [self createResultSignal];
    }

    return _resultSignal;
}

- (RACSignal *)createResultSignal {
    return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [someObject doWorkWithCompletionBlock:^(id result) {
            [subscriber sendNext:result];
            [subscriber sendCompleted];
        }
                                failure:^(NSError *error) {
            [subscriber sendError:error];
        }];

        return nil;
    }] replay];
}

这很好用,但现在我想添加工作失败时重试的功能。我可以使用 -[RACSignal retry]-[RACSignal retry:],但这不会立即通知订阅者错误。相反,我想要的是让该信号的现有订阅者收到错误,但随后调用 -resultSignal 以接收新信号,或重试现有信号。

我可以 -catch: 这个信号并在 block 中将 _resultSignal 设置为 nil,但是我不得不担心竞争条件,我认为这不是执行此操作的“响应式(Reactive)”方式。

实现此行为的适当方式是什么?

更新:

感谢@joshaber!我最终采用了我建议的方法,我认为这还不错:

- (RACSignal *)resultSignal {
    @synchronized(_resultSignal) {
        if (!_resultSignal) {
            @weakify(self);

            _resultSignal = [[self createResultSignal] catch:^RACSignal *(NSError *error) {
                @strongify(self);

                self.resultSignal = nil;
                return [RACSignal error:error];
            }];
        }

        return _resultSignal;
    }
}

- (void)setResultSignal:(RACSignal *)signal {
    @synchronized(_resultSignal) {
        _resultSignal = signal;
    }
}

最佳答案

我一直在想这个问题。如果我希望得到一个很好的答案,这对我有帮助吗? ;)

I could -catch: this signal and set _resultSignal to nil in the block, but then I'd have to worry about race conditions, and I don't think that'd be the "reactive" way to do this.

这是我倾向于的。

或者,您可以使用信号中的信号。它会发送最新的信号。现有订阅者将订阅旧信号,新订阅者将获得重试信号。但这可能需要手动使用 RACSubject,因此与其他解决方案相比,我不知道额外的复杂性是否值得。

关于ios - 仅对新订阅者进行信号重试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22160662/

相关文章:

ios - pushViewController 没有做任何事情(遵循 IAP 教程)

ios - 实例化 MPVolumeView 时新的 OutputDeviceUID 为 nil msg

ios - 如何从 Swift View 模型绑定(bind)到 Obj-c View Controller ?

使用 rac_textSignal() 时出现 Swift ReactiveCocoa 问题

ios - 我的导航栏中的图像不会显示 - 在 Swift 中

ios - 如何使用 Interface Builder 设置 UIScreenEdgePanGestureRecognizer?

ios - NSCache 没有在第一次被询问时返回数据

swift - 设计可观察对象

ios - 无法使用 ReactiveCocoa 观察 NSMutableSet 添加