GCD主线程崩溃问题(需要说明)?

3
为什么这段代码会导致崩溃?
 DispatchQueue.main.sync {
        // Operation To Perform 
 }

我们为什么要这样写:-
DispatchQueue.global().async(execute: {
    print("test")
    DispatchQueue.main.sync{
        print("main thread")
    }
})

当我们在CellForRowAt或其他方法中编写代码时,它是在主线程还是全局线程上运行?它是同步方式还是异步方式?


可能是What does main.sync in global().async mean?的重复问题。 - Prashant Tukadiya
为什么会崩溃?简而言之,调用同步并针对当前队列是死锁(调用队列等待同步块完成,但它不会启动,因为目标队列(相同)正在忙于等待同步调用完成),这可能就是崩溃的原因。 - Prashant Tukadiya
对于第二个代码块:你正在创建全局队列,然后获取主队列,因此现在没有死锁。 - Prashant Tukadiya
https://dev59.com/MlYN5IYBdhLWcg3w4bv1#46732195 - Milan Nosáľ
3个回答

3

enter image description here

根据苹果公司的说法,试图在主队列上同步执行工作项会导致死锁。因此,编写DispatchQueue.main.sync {}可能会导致死锁条件,因为除非我们手动将某些任务切换到后台队列,否则应用程序执行的所有UI操作都在主队列上执行。这也回答了您关于CellForRowAt在哪个线程中调用的问题。与UI操作或UIkit相关的所有方法都是从主线程调用的。
同步执行任务意味着阻塞线程直到任务完成,在这种情况下,您正在尝试阻塞主线程,而系统/应用程序已经执行了一些任务,这可能会导致死锁。不推荐阻塞主线程,因此我们需要异步切换到后台线程,以便不会阻塞主线程。
要了解更多信息,请访问以下链接: https://developer.apple.com/documentation/dispatch

1
为什么程序会崩溃?
DispatchQueue.main.sync {
    // Operation To Perform 
}

调用同步并针对当前队列是死锁(调用队列等待同步块完成,但它不会启动,因为目标队列(相同)正在忙于等待同步调用完成),这可能是崩溃的原因。
对于第二个块:您正在创建全局队列,然后获取主队列,因此现在没有死锁。
如果您曾经使用过信号量,那么它也有同样的问题,如果您不注意,它有两个方法wait和signal,如果您阻塞主线程,则您的代码将永远不会执行。
希望这有帮助。

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

在已经处于串行队列(如main)上的情况下调用同步操作会导致死锁。第一个进程无法完成,因为它正在等待第二个进程完成,而第二个进程无法完成,因为它正在等待第一个进程完成,以此类推。

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

从这里在主线程上调用sync,可以将任务移动到global()队列中。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接