user9315778
user9315778

Reputation:

GCD Main Thread Crash Issue (Explanation Needed)?

why do this piece of code causes crash ?

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

why we have to write this way :-

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

and when we write code in CellForRowAt or any other method in which thread it goes main or global on how it works sync or async way ?

Upvotes: 3

Views: 1947

Answers (3)

Alex Brown
Alex Brown

Reputation: 1613

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

Calling sync on a serial queue (like main) that you're already on will cause a deadlock. The first process can't finish because it's waiting for the second process to finish, which can't finish because it's waiting for the first to finish etc.

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

Calling sync on the main thread from here works as you're moving the task to the global() queue.

There's a great 2 part GCD tutorial on raywenderlich.com which I encourage you to read https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1.

Upvotes: 0

iOS_MIB
iOS_MIB

Reputation: 1895

enter image description here

According to Apple, attempting to synchronously executing a work item on main queue results into a dead-lock.

So writing DispatchQueue.main.sync {} can lead to deadlock condition as all the UI operations performed by app is performed on main queue unless we manually switch some task on the background queue. This also answer your question regarding on which thread CellForRowAt is called. All the methods related to UI operation or UIkit are called from main thread

Performing a task synchronously means blocking a thread until the task is not completed and in this case you are attempting to block main thread on which the system / app would be already performing some task and that can lead to deadlock. Blocking main thread is not at all recommended and thats why we need to switch asynchronously to a background thread so that main thread is not blocked.

To read more you can visit the following link: https://developer.apple.com/documentation/dispatch

Upvotes: 3

Prashant Tukadiya
Prashant Tukadiya

Reputation: 16426

Why crash In Short

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

calling sync and targeting current queue is a deadlock (calling queue waits for the sync block to finish, but it does not start because target queue (same) is busy waiting for the sync call to finish) and thats probably why the crash.

For Second block : You are creating global queue and then you are getting main queue so now there is no dead lock

If you have ever used semaphore which has same issue if you don't take care it has two methods wait and signal with wait if you block main thread then your code will never executed.

hope it is helpful

Upvotes: 1

Related Questions