我已经使用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
并不是必需的。
谢谢。
答案 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)
}
}
}