【问题标题】:GCD Main Thread Crash Issue (Explanation Needed)?GCD 主线程崩溃问题(需要解释)?
【发布时间】:2018-02-06 08:39:45
【问题描述】:

为什么这段代码会导致崩溃?

 DispatchQueue.main.sync {
        // Operation To Perform 
 }

为什么我们必须这样写:-

DispatchQueue.global().async(execute: {
    print("test")
    DispatchQueue.main.sync{
        print("main thread")
    }
})

当我们在 CellForRowAt 或任何其他线程中编写代码时,它会在主线程或全局线程中以同步或异步方式工作?

【问题讨论】:

标签: ios iphone swift multithreading grand-central-dispatch


【解决方案1】:

根据 Apple,尝试在主队列上同步执行工作项会导致死锁

所以写DispatchQueue.main.sync {}会导致死锁情况,因为应用程序执行的所有UI操作都在主队列上执行,除非我们手动切换后台队列上的某些任务。这也回答了您关于调用哪个线程 CellForRowAt 的问题。所有与UI操作或UIkit相关的方法都是从主线程调用的

同步执行任务意味着阻塞线程直到任务未完成,在这种情况下,您试图阻塞系统/应用程序已经执行某些任务的主线程,这可能导致死锁。完全不建议阻塞主线程,这就是为什么我们需要异步切换到后台线程,这样主线程就不会被阻塞。

要了解更多信息,您可以访问以下链接: https://developer.apple.com/documentation/dispatch

【讨论】:

    【解决方案2】:

    为什么总要崩溃

    DispatchQueue.main.sync {
        // Operation To Perform 
    }
    

    调用同步并定位当前队列是一个死锁(调用队列等待同步块完成,但它没有启动,因为目标队列(相同)正忙于等待同步调用完成),这可能是崩溃的原因.

    对于第二个块:您正在创建全局队列,然后您正在获取主队列,所以现在没有死锁

    如果您曾经使用过semaphore,如果您不小心也会遇到同样的问题 它有两个方法waitsignalwait 如果你阻止main thread 那么你的代码将永远不会执行。

    希望对你有帮助

    【讨论】:

      【解决方案3】:
       DispatchQueue.main.sync {
           // Operation To Perform 
       }
      

      在您已经使用的串行队列(如main)上调用同步将导致死锁。第一个进程无法完成,因为它正在等待第二个进程完成,而第二个进程无法完成,因为它正在等待第一个进程完成等等。

      DispatchQueue.global().async(execute: {
          print("test")
          DispatchQueue.main.sync{
              print("main thread")
          }
      })
      

      当您将任务移动到global() 队列时,从这里调用主线程上的sync 起作用。

      在 raywenderlich.com 上有一个很棒的 2 部分 GCD 教程,我鼓励您阅读 https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多