Swift-为什么DispatchGroup在此功能中不起作用?

问题描述

在返回变量之前,我正在等待exec()响应。

请不要告诉我仅使用完成处理程序并在没有idToken的情况下调用它。我知道我可以做到,但是我试图理解为什么这种逻辑不起作用。

dispatchGroup

运行:

func createtoken() -> String {
    
    var token = "empty"
    var group = dispatchGroup()
    group.enter()
    
    let currentUser = Auth.auth().currentUser
    
    currentUser?.getIDTokenForcingRefresh(true) { idToken,error in
        
        token = idToken ?? "error"
        print("Token Set")
        group.leave()
    }
    
    group.wait(timeout: dispatchTime.Now() + 10)

    return token
}

输出

print("create ")
print(createtoken())
print("done")

解决方法

如果getIDTokenForcingRefresh将其完成处理程序闭包分派回主队列,您将确切地看到所描述的行为。当执行击中wait调用时,它将阻塞主线程。但是,如果将完成处理程序闭包调度到主队列,则在wait调用超时并再次释放主线程之前,该闭包将无法运行。

您可以证实这一论点,即getIDTokenForcingRefresh正在通过各种方式在主线程上调用其完成处理程序:

  • 尝试删除timeout,在这种情况下,如果使用主队列/线程,则此代码将完全死锁。

  • 打印Thread.isMainThread

  • 添加前提条件语句:

    dispatchPrecondition(condition: .onQueue(.main))
    
  • 在此闭包中设置一个断点,然后让调试器告诉您使用了哪个线程。

但是您说的很对:一般应避免使用wait模式。