我在互联网上搜索了所有线程swift 4,这就像我在下面的代码中运行它一样:
var ads = [Ads]()
func viewDidLoad() {
DispatchQueue.global(qos: .userInteractive).async {
requestAds()//set self.ads from API and need 1-5 second to response
DispatchQueue.main.async {
self.ads = getAds()
print(self.ads.count) //always 0 because this code run before request completed
self.adsTableView.reloadData()
}
}
}
但是所有的代码都像不使用DispatchQueue一样运行:
requestAds()
self.ads = getPromos()
print(self.ads.count)
self.promoTableView.reloadData()
这是requestAds():
func requestAds() {
let adsProvider = AdsDataService.instance.adsProvider
adsProvider.request(.allAds, completion: { (result) in
switch result {
case .success(let response):
print(response.debugDescription)
guard let reqAds = try? JSONDecoder().decode([Ads].self, from: response.data) as [Ads] else {
print("Can't decode json")
return}
self.ads = reqAds
case .failure(let error):
print(error)
}
})
}
和我的getAds():
func getAds() → [Ads] {
requestAds()
return ads
}
当我使用服务器运行代码中的代码DispatchQueue.main.asyncAfter(deadline: .now() + 6.0, execute: code)
使用延迟6秒(因为我无法确定服务器时间响应)时这是有效的,但我认为这是实现此错误的方法。
任何人都有同样的问题吗?或者可以帮我吗?谢谢!
答案 0 :(得分:0)
您无法预先设置响应时间,因为它未确定。服务器响应的时间取决于许多情况,如互联网连接,服务器容量等。
从服务器下载数据时,您必须等到请求完成。我建议您阅读有关使用API here的更多信息。
尝试这样的事情:
var ads = [Ads]()
func viewDidLoad() {
requestAds { [weak self] (ads) in
self?.ads = ads
DispatchQueue.main.async {
self?.adsTableView.reloadData()
}
}
}
func requestAds(completion: ([Ads], Error?) -> ()) {
let adsProvider = AdsDataService.instance.adsProvider
adsProvider.request(.allAds) { (result) in
switch result {
case .success(let response):
guard let reqAds = try? JSONDecoder().decode([Ads].self, from: response.data) as [Ads] else {
completion([], nil)
return
}
completion(reqAds, nil)
case .failure(let error):
completion([], error)
}
}
}
这里的要点是:
我们使用线程同时执行多个操作,而不是等待服务器的响应。您可以从Apple Guide或GCD intro post了解线索。