- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码,它使用 DispatchGroup
在任务完成时收到通知,如下所示:
func getSomething(completion: ()->()) {
completion()
}
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
myGroup.enter()
getSomething {
myGroup.leave()
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
DispatchQueue.global().async {
print("We are doing background work")
doSomeWork {
print("We are done with the work - but on main thread now!!!")
}
}
所以我遇到的问题是我在线程上调用某个函数,该函数有一个在某个固定队列上调用的完成。
我的选择是:
但我对任何选项都不满意...我不想有这么多的调度。
想象一下:
DispatchQueue.global().async {
print("We are doing background work")
doSomeWork {
DispatchQueue.global().async {
print("Now we are in background again")
}
}
}
这已经是一个 3 级闭包,并且不太好用,特别是如果在后台异步调用中我们有另一个闭包或级别。
任何关于在这里做什么的帮助都会很棒!谢谢
最佳答案
The issue is that I‘m calling a function bla({ //block code }) on a background queue. bla() calls the completion handler on the main thread though, due to dispatch groups – Janosch Hübner
再次检查您的代码片段
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
myGroup.enter()
getSomething {
myGroup.leave()
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
并且看到,因为 getSomething
是同步的,所以您可以简单地编写
func doSomeWork(completion: ()->()) {
//let myGroup: DispatchGroup = DispatchGroup()
for _ in 0..<10 {
//myGroup.enter()
getSomething {
//myGroup.leave()
}
}
//myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
//}
}
如果 getSomething
应该是异步的,请使用正确的 API 在某个组中运行它
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
let queue = DispatchQueue.global()
for _ in 0..<10 {
//myGroup.enter()
queue.async(group: myGroup) {
getSomething {
//myGroup.leave()
}
}
}
myGroup.notify(queue: DispatchQueue.main) { // this here is the key
completion()
}
}
在同一个线程(最好是在同一个队列上)运行 completion()
与 doSomeWork(completion: ()->())
很简单.
func doSomeWork(completion: ()->()) {
let myGroup: DispatchGroup = DispatchGroup()
let queue = DispatchQueue.global()
for _ in 0..<10 {
//myGroup.enter()
queue.async(group: myGroup) {
getSomething {
//myGroup.leave()
}
}
}
//myGroup.notify(queue: DispatchQueue.main) { // this here is the key
myGroup.wait()
completion()
//}
}
检查下一个 Playground 页面,看看 DispatchQueue.concurrentPerform 如何改变您的设计以及组通知如何工作
import PlaygroundSupport
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q0 = DispatchQueue.global()
let q1 = DispatchQueue(label: "my_queue", attributes: .concurrent)
let g = DispatchGroup()
let g1 = DispatchGroup()
q0.async(group: g) {
print("1 message from \(q0): will do some concurrent jobs in the background")
DispatchQueue.concurrentPerform(iterations: 5, execute: { (i) in
sleep(1)
print("\t",i)
})
print("2 message from \(q0): all concurrent jobs done")
q0.async(group: g) {
print("3 some other long time running on group...")
sleep(3)
print("3 ex")
}
q0.async(group: g1) {
print("? some other long time running on gifferent group...")
sleep(4)
print("? ex")
}
g1.notify(queue: .main, execute: {
print("g1 empty")
})
}
print("4 continue on main")
g.notify(queue: q1) {
print("5 message from \(q1): finished a")
DispatchQueue.main.async {
sleep(1)
print("6 from main, should stop playground execution?")
//PlaygroundPage.current.finishExecution()
}
print("7 message from \(q1): finished b")
}
g1.notify(queue: .main) {
print("8 from main, g1 is empty.")
}
print(" ... continue")
在我的环境中打印
1 message from <OS_dispatch_queue_global: com.apple.root.default-qos>: will do some concurrent jobs in the background
4 continue on main
... continue
8 from main, g1 is empty.
0
2
1
3
4
2 message from <OS_dispatch_queue_global: com.apple.root.default-qos>: all concurrent jobs done
3 some other long time running on group...
? some other long time running on gifferent group...
3 ex
5 message from <OS_dispatch_queue_concurrent: my_queue>: finished a
7 message from <OS_dispatch_queue_concurrent: my_queue>: finished b
6 from main, should stop playground execution?
? ex
g1 empty
关于使用 DispatchGroup 进行 Swift 线程处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54544033/
我想知道以下情况。 我在一个函数中有一个 DispatchGroup。现在我在后台线程上进入组并调用 wait()。 func test() { let group = DispatchGrou
下面的代码我用来进行并发 API调用。不知怎的,这个方法返回多次。我已经在没有 DispatchGroup 的情况下进行了测试,它按预期工作。帮我找出为什么它多次调用。 我的代码片段: fu
是否可以从另一个类访问 DispatchGroup?假设我在类 Loginfunctions.swift 中有以下函数(在 func 中定义了 var loginQueue = DispatchGro
我正在尝试使用 Firebase 身份验证来注册用户。当用户注册时,我希望将他们添加到我的 Users 中Firestore 中的集合以及 Users授权部分。 createUser(withEmai
我正在尝试链接两个调度组,但我的代码总是在随机位置崩溃。 我的功能是这样的: func getAllActivities(userUID: String, _ completionHandler: @
我想使用 DisaptchGroup 在遍历并将元素追加到数组后调用 func。 这是 firebase 节点的样子 { "tags": { "NewYork":
enter code here我用调度组尝试了很多东西,但我无法获得稳定的结果。自从我的服务器以来,我使用 Alamofire 获取数据。我在 Helper 类中编写了一个函数,并在 AppDeleg
我目前有一个数组,它遍历图像路径的值,并希望在第一个 for 循环中异步检索这些图像。我试过使用两个调度组,但总是在检索图像之前返回完成处理程序。 static func getAllEntriesW
我创建了一个 DispatchGroup 并运行了 2 个异步任务。一个在 main 上,另一个在 global() 上。 据我所知,DispatchGroup.notify 的 block 应该在所
因此,我花了一些时间尝试让 DispatchGroup 在长时间的异步操作完成之前阻止 for 循环迭代。我发现的大多数示例都相当简单明了,但我似乎无法让我的简单测试用例按预期工作。 let grou
我有两个函数(或任务),我想一个接一个地运行,我正在使用 DispatchGroup 来跟踪它们并在它们完成时通知我。现在它们正在主线程中完成,但我想在后台线程中运行这些任务。我将如何去做呢?我尝试了
以下是否会产生可能的竞争条件? let syncGroup = DispatchGroup() var tempData: [Int] for index in 1...10 { sync
我必须停止我的代码一秒钟,以便在继续之前同步服务器数据库。 下面的所有代码片段都是从主线程运行的。 我首先使用了这个: // code 1 DispatchQueue.main.asyncAfter(
我正在进行两个异步网络调用,并且想使用一个 Dispatch Group 来等待调用完成然后恢复。我的程序卡住了。 class CommentRatingViewController: UIViewC
我想让对服务的调用同步,因为我希望我的调用返回已使用泛型映射的对象。 这是代码: func execute(request: HttpRequest, responseType: T.Type) th
我遇到一种情况,我需要等待一组任务完成才能执行某些 UI 渲染代码。 其中一些任务是网络请求,它们始终会完成并离开调度组。然而,有些不是网络请求,可能会也可能不会完成。如果一项任务未完成,并且离开的调
在使用异步递归调用 API 时,我无法理解如何使用 GCD。 下面是三个类似方法之一,包含相同的逻辑,只是针对不同的数据和 API 端点。如果没有下一页请求,该方法应该完成并且下一个方法应该开始。 我
我在理解或使用 Dispatchgroup 时遇到问题。我已经阅读了很多关于它们的内容,但是大多数示例/文档都非常模糊或者与我想做的不一样,但是每次我提到我的问题时,每个人都说“使用调度组!”。 这是
问题描述: 我想通过“DispatchGroup”执行一系列异步任务,当所有这些任务完成时它返回结果。另外,我想设置限制进程的超时时间,到时候把成功的结果发给我。我使用了以下结构: 代码块 let m
在下面的代码中,附加到数组是否安全?是否保证维持秩序? let processedData: [SomeType] = [] let dispatchGroup = DispatchGroup() f
我是一名优秀的程序员,十分优秀!