ReactiveSwift的终身目标



我已经使用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真的没有必要。

提前谢谢。

您没有必要为了保持订阅的有效性而保留startWithResult的结果,这是正确的。文件的相关部分写道:

Signal必须公开保留,以便附加新的观察者,但不一定是为了保持事件流的活动性。此外,只要仍然存在活跃的观察者,Signal就保持其自身。

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

相反,Lifetime是关于取消操作。在这种情况下,因为您已将startWithResult的结果附加到ServiceWrapped的生存期,所以当释放ServiceWrapped对象时,该操作将被取消。如果省略lifetime +=,则即使解除分配ServiceWrapped,操作也将继续。

如果您有一个从web加载图像的视图控制器,那么这就是为什么有用的一个实际例子。如果用户在图像加载完成之前关闭了视图控制器,那么您可能想要取消web请求。您可以通过将图像加载生成器与视图控制器的生存期绑定来实现这一点。这不是为了保持网络请求的有效性,而是在不再需要时取消它。

撇开风格不谈,文档建议您使用运算符,而不是处理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)
}
}
}

相关内容

  • 没有找到相关文章

最新更新