【发布时间】:2021-09-26 13:44:55
【问题描述】:
每次我调用这个 api https://foodish-api.herokuapp.com/api/ 我都会得到一张图片。我不想要一张图片,我需要其中的 11 张,所以我进行了循环以获取 11 张图片。 但是我不能做的是在循环完成后重新加载集合视图。
func loadImages() {
DispatchQueue.main.async {
for _ in 1...11{
let url = URL(string: "https://foodish-api.herokuapp.com/api/")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String : String]
print(json!["image"]!)
self.namesOfimages.append(json!["image"]!)
} catch {
print("JSON error: \(error.localizedDescription)")
}
}.resume()
}
}
self.collectionV.reloadData()
print("after resume")
}
【问题讨论】:
-
视情况而定。您想在每次完成时刷新 11 次吗?或者当所有 11 个都完成时。如果是前者,请按照 ahem 的建议,在更新
namesOfimages之后立即放置。如果是后者,请使用调度组,在每个请求之前调用enter,在完成处理程序中调用leave,然后添加一个将重新加载表的notify块。这已经被概述了很多次,所以如果这个模式不熟悉,你会发现很多 S.O.关于这个话题的答案。 -
一些不相关的观察: 1. 外部
DispatchQueue.main.async是多余的,因为dataTask已经是异步的。 2. 你确实需要这个异步调度到主线程的地方是namesOfimages的更新。您当前正在从URLSession后台队列更新此内容,引入了数据竞争。您不想在没有同步的情况下从后台线程更新模型属性(或者只是从主线程进行更新,这是最简单的同步方式)。 -
3.如果执行 11 个网络请求,您可能会像上面那样愉快地同时启动所有 11 个请求,但如果启动的次数远不止这些,您可能希望限制将要启动的并发请求的数量在任何给定的时刻。
标签: swift api uicollectionview urlsession