gpt4 book ai didi

ios - 关闭和其他 GCD 问题中的 Weak DispatchGroup

转载 作者:行者123 更新时间:2023-11-28 07:23:24 24 4
gpt4 key购买 nike

Swift 闭包强烈捕获引用类型。

DispatchGroup 是一个引用类型。

我的问题与以下代码有关:

func getUsername(onDone: @escaping (_ possUsername: String?) -> ())
{
//Post request for username that calls onDone(retrievedUsername)...
}

func getBirthdate(using username: String?, onDone: @escaping (_ possBday: String?) -> ())
{
//Post request for token that calls onDone(retrievedToken)...
}

func asyncTasksInOrder(onDone: @escaping (_ resultBDay: String?) -> ())
{
let thread = DispatchQueue(label: "my thread", qos: .userInteractive, attributes: [],
autoreleaseFrequency: .workItem, target: nil)
thread.async { [weak self, onDone] in
guard let self = self else {
onDone(nil)
return
}
let dg = DispatchGroup() //This is a reference type
var retrievedUsername: String?
var retrievedBday: String?

//Get username async first
dg.enter()
self.getUsername(onDone: {[weak dg](possUsername) in
retrievedUsername = possUsername
dg?.leave() //DG is weak here
})
dg.wait()

//Now that we've waited for the username, get bday async now
dg.enter()
self.getBirthdate(using: retrievedUsername, onDone: {[weak dg](possBday) in
retrievedBday = possBday
dg?.leave() //DG is also weak here
})
dg.wait()

//We've waited for everything, so now call the return callback
onDone(retrievedBday)
}
}

所以 asyncTasksInOrder(onDone:) 中的两个闭包每个捕获 dg,我的 DispatchGroup。

  1. 甚至有必要捕获我的调度组吗?
  2. 如果我不捕获它,我怎么知道我有一个保留周期?
  3. 如果调度组在其中一个回调执行期间消失了怎么办?它会因为等待而蒸发吗?
  4. 像这样经常实例化一个 DispatchQueue 是否不必要地昂贵(忽略 .userInteractive)?我之所以问这个特定问题,是因为在 Android 中启动线程非常昂贵(如此昂贵以至于 JetBrains 将大量资源用于 Kotlin 协程)。
  5. dg.notify(...) 如何发挥所有这些作用?为什么在 dg.wait() 做同样的事情时还要有一个通知方法?

我觉得我对 GCD 的理解不是万无一失的,所以我想建立一些信心。有什么可以批评的也请批评指正。非常感谢您的帮助。

最佳答案

1) 不,调度组是隐式捕获的。您甚至不需要在 async 中捕获 self,因为 GCD 闭包不会导致保留周期。

2) 没有保留周期。

3) 实际上,您是在滥用 DispatchGroup 来强制将异步任务变为同步。

4) 不,GCD 非常轻量级。

5) DispatchGroup 的主要目的是在所有异步任务(例如在重复循环中)完成时通知,而不考虑顺序。


更好的解决方案是嵌套异步任务。只需两项任务,厄运金字塔 是可控的。

func asyncTasksInOrder(onDone: @escaping (String?) -> Void)
{
let thread = DispatchQueue(label: "my thread", qos: .userInteractive, autoreleaseFrequency: .workItem)
thread.async {

//Get username async first
self.getUsername { [weak self] possUsername in
guard let self = self else { onDone(nil); return }

//Now get bday async
self.getBirthdate(using: possUsername) { possBday in

//Now call the return callback
onDone(possBday)
}
}
}
}

关于ios - 关闭和其他 GCD 问题中的 Weak DispatchGroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57324405/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com