【问题标题】:Swift - Why is DispatchGroup not working in this function?Swift - 为什么 DispatchGroup 在这个函数中不起作用?
【发布时间】:2020-11-10 23:21:30
【问题描述】:

在返回变量之前,我正在等待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")

输出:

create 
empty
done
Token Set

【问题讨论】:

    标签: swift completionhandler dispatchgroup


    【解决方案1】:

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

    你可以确认这个论点,getIDTokenForcingRefresh 正在主线程上以多种方式调用它的完成处理程序:

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

    • 打印Thread.isMainThread

    • 添加前置条件语句:

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

    但您说的很对:wait 模式通常应避免使用。

    【讨论】:

      猜你喜欢
      • 2022-12-03
      • 2021-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      相关资源
      最近更新 更多