【发布时间】:2019-12-06 11:16:26
【问题描述】:
我的应用程序 (Swift 5) 使用 for 循环和 i.a. 中的异步完成处理程序将文件发送到服务器。一个信号量,以确保同时只发送一个文件。
如果上传失败或出现异常,我想打破循环以显示错误消息。
我的代码:
let group = DispatchGroup()
let queue = DispatchQueue(label: "someLabel")
let sema = DispatchSemaphore(value: 0)
queue.async {
for (i,item) in myArray.enumerated() {
group.enter()
do {
let data = try Data(contentsOf: item.url)
ftpProvider.uploadData(folder: "", filename: item.filename, data: data, multipleFiles: true, completion: { (success, error) in
if success {
print("Upload successful!")
} else {
print("Upload failed!")
//TODO: Break here!
}
group.leave()
sema.signal()
})
sema.wait()
} catch {
print("Error: \(error.localizedDescription)")
//TODO: Break here!
}
}
}
group.notify(queue: queue) {
DispatchQueue.main.async {
print("Done!")
}
}
添加break 会给我一条错误消息:
无标签的'break'只允许在循环或开关内,一个有标签的 退出 if 或 do 需要 break
向循环添加标签 (myLoop: for (i,s) in myArray.enumerated()) 也不起作用:
使用未解决的标签“myLoop”
break self.myLoop 也失败了。
在group.enter() 之前添加print 证明循环不是在第一个文件上传完成之前完成,而是在“上传成功”/“上传失败”之前打印文本(正如它应该的那样)。因为这种破坏应该是可能的:
如何中断循环,以便在group.notify 中显示错误对话框?
【问题讨论】:
-
可以在这里找到类似的问题:reddit.com/r/swift/comments/bih0zn/…
-
使用异步操作和串行操作队列,而不是丑陋的信号量(在您的情况下该组毫无意义)。好处是如果无法上传文件,您可以取消所有操作。
-
@swiftlynx 您链接到的代码也使用递归(如 Sh_Khan 的回答),这意味着重组整个事情,因为它比我在问题中显示的要多。我宁愿跳出循环。
-
@vadian 在第一个文件上传之前,很快就摆脱了该组,
group.notify(queue: queue)也立即调用了print("Done!")。代码已经在后台线程中运行。我要调查OperationQueues,好的。同时:是否有可能用我当前的代码跳出循环? -
@Neph 不,不是。
标签: swift foreach break completionhandler