main.async vs main.sync() vs global().async in Swi

2019-04-29 02:34发布

Example A:- This cause App Crash.

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

Example B:- But This don't

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

As per my knowledge,

  • x.sync means doing thing in main thread/UI thread and x.async means doing in background thread.
  • Global means performing something with concurrent queue i.e Parallel task.

Quest1:- So why does my app crashed when i performed task in background thread i.e main.async and than call main thread to update UI.

Quest2:- Is there any difference in main.async & global().async.

3条回答
叼着烟拽天下
2楼-- · 2019-04-29 02:42

In simple term i come to conclusion that -

  • Queue- There are 3 Types of Queue i.e. 1 Main Queue, 4 Global Queue and Any No. of Custom Queues.
  • Threads- One is Main Thread and other background threads which system provides to us.

DispatchQueue.main.async

-It means performing task in main queue with using of background thread (w/o blocking of UI) and when task finish it automatic Updated to UI because its already in Main Queue.

DispatchQueue.global().async along with global().sync

It means performing task in Global Queue with using of background thread and when task finish, than global().sync use bring the work from globalQueue to mainQueue which update to UI.

Reason of My App Crash

I was trying to bring the completed task to MainQueue by using(main.sync), but it was already on MainQueue because i hadnt switched the Queue, and this create DeadLock (MainQueue waiting for itself), causes my app crash

查看更多
ゆ 、 Hurt°
3楼-- · 2019-04-29 02:58

You were mixing up the terms sync/async and main/global.

Sync - Run some task synchronously (i.e. the thread which can be main/global/any other thread will wait for the task to complete)

Async - Run some task asynchronously (i.e. the thread which can be main/global/any other thread will push the task to a queue and continue executing next steps outside your block. It wont wait)

Now lets go one by one in your code which was crashing :
Lets put some names for our threads so it will be easy for our understanding:
1) ThreadA - Which encounters your dispatch statements (this can also be Main thread, but for explanation purpose I feel its better)
2) ThreadB - Global thread which gets created when you submit some task.
3) ThreadMain - Main thread

Example A:
DispatchQueue.main.async - ThreadA comes and execute this statement and put your block on ThreadMain and moves on (since its async) to next steps after the block.

Now lets talk about ThreadMain, what it will do from here. Since ThreadMain got a block (submitted by ThreadA) it starts executing step by step and suddenly it sees 'DispatchQueue.main.sync' and submits the inner block on to the same TheradMain queue and keeps onnnnn waitingggggg (since its sync). So literally you are making the ThreadMain into deadlock situation.

查看更多
爷的心禁止访问
4楼-- · 2019-04-29 02:59

In first case, you run the code on main and then you use main.sync on the main thread. In essence, you are trying to tell the main queue to wait for itself - which is obviously nonsense and therefore it causes crash.

In the second case, you run the code on the background thread, and then you use main.sync to wait until the main thread can run the block provided in main.sync.

In general, I would use async and not sync all the time, unless sync is necessary - and always sync one thread (DispatchQueue) with a different one, never with the same one.

查看更多
登录 后发表回答