ReactiveSwift的终生用途

时间:2018-11-28 01:52:05

标签: swift reactive-swift

我已经使用ReactiveSwift几个月了,但是有一些我不完全了解的内容:生存期对象。

例如,假设我有一个SignalProducer,它将进行API调用,它包装在一个类上:

class ServiceWrapped {

    private let service: Service // the method called on this object returns the SignalProducer
    private let (lifetime, token) = Lifetime.make()

    // more stuff

    func fetchSomething(completion: @escaping (Value?, Error?) -> Void) {
        lifetime += service.fetchSomething()
            .startWithResult { result in
                switch result {
                case .success(let value):
                    completion(value, nil)
                case .failure(let error):
                    completion(nil, error)
                }
        }
    }
}

我的问题是:在这种情况下是否有必要使用lifetime

我知道lifetime会保留服务调用,因此它在返回时会有一些东西,但是由于它也包裹在ServiceWrapped上,因此我认为使用lifetime并不是必需的。

谢谢。

1 个答案:

答案 0 :(得分:4)

您是正确的,无需保留startWithResult的结果即可使订阅保持活动状态。 relevant part of the documentation says

  

Signal必须公开保留,以附加新的观察者,但不一定要保持活动的持续性。而且,只要有一个活跃的观察者,Signal就会保留下来。

只要不处理从startWithResult返回的对象,即使不保留它,该操作也将继续。

相反,Lifetime取消操作有关。在这种情况下,因为您已经将startWithResult的结果附加到ServiceWrapped的生命周期中,所以当释放ServiceWrapped对象时,该操作将被取消。如果省略lifetime +=,那么即使释放了ServiceWrapped,该操作也会继续。

为什么有用的一个实际例子是,如果您有一个视图控制器,该控制器从Web加载图像。如果用户在图像加载完成之前解雇了视图控制器,则您可能要取消Web请求。您可以通过将图像负载生成器绑定到视图控制器的生存期来实现。这不是要使Web请求保持活动状态,而是要在不再需要时取消它。

除了样式之外,documentation recommends you use operators rather than handling the result of the startWithResult

func fetchSomething(completion: @escaping (Value?, Error?) -> Void) {
    service.fetchSomething()
        .take(during: lifetime)
        .startWithResult { result in
            switch result {
            case .success(let value):
                completion(value, nil)
            case .failure(let error):
                completion(nil, error)
            }
    }
}