main.async vs main.sync()vs global()。Swift3中的异步GCD

问题描述:

示例A: - 这会导致应用程序崩溃。main.async vs main.sync()vs global()。Swift3中的异步GCD

DispatchQueue.main.async {   
     let url = URL(string: imageUrl) 
     do { 
      let data = try Data(contentsOf: url!) 
       DispatchQueue.main.sync { 
        self.imageIcon.image = UIImage(data: data) 
       } 
      } 

实例B: - 但这并不

DispatchQueue.global().async { 
     let url = URL(string: imageUrl) 
     do { 
      let data = try Data(contentsOf: url!) 
       DispatchQueue.main.sync { 
        self.imageIcon.image = UIImage(data: data) 
       } 
      } 

按我的知识,

  • x.sync意味着在主线程/ UI线程和x.async做的事意味着 在后台线程中执行。
  • 全局意味着执行一些并发队列,即并行 任务。

Quest1: - 那么为什么我的应用程序崩溃时,我在后台线程执行任务,即main.async和比调用主线程来更新用户界面。

任务2: - main.async & global()。async是否有区别。

+1

你似乎有你的术语混淆,主=主线程,全局=后台线程,同步意味着执行串行任务(在该队列,例如主/全球) ,异步是并发的(再次在单个队列上的并发任务),我有一个很好的页面解释这在*文档,但他们已经关闭它现在下来:( – Fonix

+1

“x.sync意味着做主线程/ UI线程和x.async意味着在后台线程中做的事情” - 我不认为这是真的,你不应该想到队列为线程(他们不一样)。调用'async'意味着它不会阻塞,但是你在'DispatchQueue.main'上调用它,这是一个保证在主线程上运行的队列。 – Ssswift

+0

我从[链接]中了解到“x.sync表示在主线程/ UI线程中执行的操作”... https://*.com/questions/42772907/what-does-main-sync-in- global-async-mean –

在简单术语我来结论 -

  • 队列 - 有3种类型,即队列1主队列,4全局队列和自定义队列的任何编号。
  • 主题 - 一个是主线程和其他后台线程,系统 提供给我们。

DispatchQueue.main.async

使用后台线程的(W/O UI的阻挡),而当任务结束它自动执行更新在主队列任务 - 它手段UI因为其已经在主队列中。

DispatchQueue.global()。全球()。同步异步沿

这意味着全局队列使用后台线程和任务时后执行任务,比全球()。同步使用将工作从globalQueue带到更新为UI的mainQueue

原因我的应用程序崩溃

我试图用(main.sync)把完成的任务MainQueue,而是因为我说好的切换队列它已经在MainQueue,这创建DeadLock(MainQueue等待自己),导致我的应用程序崩溃

在第一种情况下,您运行main上的代码,然后在主线程上使用main.sync。实质上,你试图告诉main队列等待自己 - 这显然是无稽之谈,因此它会导致崩溃。

在第二种情况下,运行在后台线程的代码,然后你用main.sync等到main线程可以运行在main.sync提供的块。

一般来说,我会一直使用async而不是sync,除非sync是必要的。

+1

是的,'sync'只是意味着要等到这个块完成执行,'async'不会等待。在主线程中一定要小心使用'sync',否则会阻塞你的UI更新 – Fonix

+0

我知道global()。async意味着在后台执行任务,但main.async意味着什么? –

+0

感谢您的帮助,我发布了我的最终结论..请好好检查一下.. –

您在混合使用术语sync/async和main/global。

同步 - 同步运行某些任务(即线程可以是主/全球/任何其他线程将等待任务完成)

异步 - 异步运行的一些任务(即线程可以是主。/全球/任何其他线程将推动任务队列中,并继续执行你的外块下一步它不会等待)

现在让我们去一一在你的代码是崩溃:
让我们把一些名字我们的线程,所以我们很容易理解:
1)ThreadA - 遇到你的调度语句s(这也可以是主线程,但为了解释的目的,我觉得它更好)
2)ThreadB - 当您提交某个任务时创建的全局线程。
3)ThreadMain - 主线程

实例A:
DispatchQueue.main.async - ThreadA中来,并执行该语句,并把你的块ThreadMain和移动(因为它的异步)后的后续步骤块。

现在让我们来谈谈ThreadMain,它会从这里做些什么。由于ThreadMain获得了一个块(由ThreadA提交),它开始逐步执​​行,并突然看到'DispatchQueue.main.sync'并将内部块提交到相同的TheradMain队列并保持onnnnn waitingggggg(自其同步以来)。所以从字面上看,你正在使ThreadMain陷入僵局。

+0

main.async在后台执行任务,并且不会与MainThread同步工作,我是否正确?? ... –

+0

感谢您的帮助,我发布了我的最后的结论..好心检查它.. –