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.
In simple term i come to conclusion that -
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
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.
In first case, you run the code on
main
and then you usemain.sync
on the main thread. In essence, you are trying to tell themain
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 themain
thread can run the block provided inmain.sync
.In general, I would use
async
and notsync
all the time, unlesssync
is necessary - and always sync one thread (DispatchQueue
) with a different one, never with the same one.