如何对不同的 ServiceProtocol 使用多线程操作 - Swift
How to use multithreaded operations for different ServiceProtocol - Swift
我正在尝试在我的应用程序中使用 OperationQueue 的多线程操作。
确实,我想在启动期间从所有不同的网络服务中获取我的所有数据,以便在我到达主页时一切就绪。
但我不知道如何正确地做到这一点。
下面是一些可视化代码:
class LauncherService {
weak var serviceForecast: ForecastServiceProtocol?
weak var serviceRadar: RadarServiceProtocol?
weak var serviceWarning: WarningServiceProtocol?
weak var serviceRain: RainServiceProtocol?
init(serviceForecast: ForecastServiceProtocol = ForecastService.shared,
serviceRadar: RadarServiceProtocol = RadarService.shared,
serviceWarning: WarningServiceProtocol = WarningService.shared,
serviceRain: RainServiceProtocol = RainService.shared) {
self.serviceForecast = serviceForecast
self.serviceRadar = serviceRadar
self.serviceWarning = serviceWarning
self.serviceRain = serviceRain
}
func requestAllServices(forCity city: City, completion: ((Result<Bool, ErrorResult>) -> Void)? = nil) {
if let lat = city.lat,
let lon = city.lon {
self.fetchForecast(lat: lat, lon: lon)
self.fetchRain(lat: lat, lon: lon)
}
self.fetchWarning()
self.fetchRadar()
}
}
我想等到所有服务都完成工作后再"notify" evertyhing is ready to go
.
的主页
这里是来自所有不同 ServiceProtocol 的方法的实现:
我只给你看一个,但是所有服务的实现是完全一样的:
func fetchForecast(lat: String, lon: String, completion: ((Result<Bool, ErrorResult>) -> Void)? = nil) {
guard let service = serviceForecast else {
completion?(Result.failure(ErrorResult.custom(string: "Missing service")))
return
}
service.fetchForecast(lat: lat, lon: lon) { result in
DispatchQueue.main.async {
switch result {
case .success(let forecast) :
// DO something with this Forecast Model Object
// Add it in an array on return in completion
// But I would like to regroup all the different Model Objects from all my services.
completion?(Result.success(true))
break
case .failure(let error) :
print("Something went wrong - \(error)")
completion?(Result.failure(error))
break
}
}
}
}
我已阅读 OperationQueue 是我的用例在此处采用的解决方案。
我应该实现这样的东西吗?
let queue = OperationQueue()
for service in services {
queue.addOperation {
self.fetch()
}
}
queue.waitUntilAllOperationsAreFinished()
您可以使用 DispatchGroup
:
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
fetchForecast {
dispatchGroup.leave()
}
dispatchGroup.enter()
fetchRain {
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
print("All done")
}
最后一个块将在两个请求都完成加载后执行。
我正在尝试在我的应用程序中使用 OperationQueue 的多线程操作。
确实,我想在启动期间从所有不同的网络服务中获取我的所有数据,以便在我到达主页时一切就绪。
但我不知道如何正确地做到这一点。
下面是一些可视化代码:
class LauncherService {
weak var serviceForecast: ForecastServiceProtocol?
weak var serviceRadar: RadarServiceProtocol?
weak var serviceWarning: WarningServiceProtocol?
weak var serviceRain: RainServiceProtocol?
init(serviceForecast: ForecastServiceProtocol = ForecastService.shared,
serviceRadar: RadarServiceProtocol = RadarService.shared,
serviceWarning: WarningServiceProtocol = WarningService.shared,
serviceRain: RainServiceProtocol = RainService.shared) {
self.serviceForecast = serviceForecast
self.serviceRadar = serviceRadar
self.serviceWarning = serviceWarning
self.serviceRain = serviceRain
}
func requestAllServices(forCity city: City, completion: ((Result<Bool, ErrorResult>) -> Void)? = nil) {
if let lat = city.lat,
let lon = city.lon {
self.fetchForecast(lat: lat, lon: lon)
self.fetchRain(lat: lat, lon: lon)
}
self.fetchWarning()
self.fetchRadar()
}
}
我想等到所有服务都完成工作后再"notify" evertyhing is ready to go
.
这里是来自所有不同 ServiceProtocol 的方法的实现:
我只给你看一个,但是所有服务的实现是完全一样的:
func fetchForecast(lat: String, lon: String, completion: ((Result<Bool, ErrorResult>) -> Void)? = nil) {
guard let service = serviceForecast else {
completion?(Result.failure(ErrorResult.custom(string: "Missing service")))
return
}
service.fetchForecast(lat: lat, lon: lon) { result in
DispatchQueue.main.async {
switch result {
case .success(let forecast) :
// DO something with this Forecast Model Object
// Add it in an array on return in completion
// But I would like to regroup all the different Model Objects from all my services.
completion?(Result.success(true))
break
case .failure(let error) :
print("Something went wrong - \(error)")
completion?(Result.failure(error))
break
}
}
}
}
我已阅读 OperationQueue 是我的用例在此处采用的解决方案。
我应该实现这样的东西吗?
let queue = OperationQueue()
for service in services {
queue.addOperation {
self.fetch()
}
}
queue.waitUntilAllOperationsAreFinished()
您可以使用 DispatchGroup
:
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
fetchForecast {
dispatchGroup.leave()
}
dispatchGroup.enter()
fetchRain {
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
print("All done")
}
最后一个块将在两个请求都完成加载后执行。