【发布时间】:2017-07-04 18:12:04
【问题描述】:
我正在尝试设置用于下载图像的迭代。整个过程正常,但看看控制台的输出,似乎有问题。
func download() {
let logos = [Logos]()
let group = DispatchGroup()
logos.forEach { logo in
print("enter")
group.enter()
if logo?.data == nil {
let id = logo?.id as! String
if let checkedUrl = URL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/\(id).png") {
print(checkedUrl)
LogoRequest.init().downloadImage(url: checkedUrl) { (data) in
logo?.data = data
print("stored")
group.leave()
print("leave")
}
}
}
}
print("loop finished")
}
输出:
enter
http://www.apple.com/euro/ios/ios8/a/generic/images/og.png
enter
http://www.apple.com/euro/ios/ios8/a/generic/images/eg.png
enter
http://www.apple.com/euro/ios/ios8/a/generic/images/sd.png
enter
http://www.apple.com/euro/ios/ios8/a/generic/images/hd.png
loop finished
stored
leave
stored
leave
stored
leave
stored
leave
看起来迭代根本不关心进入和离开 DispatchGroup()。网络请求几乎同时被触发。在我看来,输出应该是这样的:
enter
http://www.apple.com/euro/ios/ios8/a/generic/images/og.png
stored
leave
enter
http://www.apple.com/euro/ios/ios8/a/generic/images/eg.png
stored
leave
...
loop finished
我监督了什么?能得到一些想法会很棒。
【问题讨论】:
-
是 DispatchGroup 行为不正确的唯一问题吗?还是您的 Web 请求的处理方式也存在操作问题?
-
这是因为您在提交请求后只是打印“循环完成”。正如 J. Doe 所说,如果您想在所有这些调度组完成时收到通知,请使用
group.notify。 -
不相关,但如果
logo?.data不是nil或者如果 URL 解包失败,您的group.enter()和group.leave()调用将不平衡,并且您的组将永远不会完成。这不是这里的问题,但你应该警惕这一点。您要确保enter和leave调用将始终保持平衡,一对一。 -
@AgnosticDev:不,不存在操作问题。该代码最多可用于 10 个值。但是以 100 运行它,应用程序崩溃了。所以请求不会异步执行。
-
@Rob:所以你认为我应该添加第二个
group.leave()?就像我在代码中编辑的那样?
标签: swift cocoa asynchronous iteration dispatch