Mahesh S
Mahesh S

Reputation: 329

Difference Between DispatchQueue.sync vs DispatchQueue.async

Im trying to understand the Dispatch Sync and Dispatch Async, I know that its executes in sync and async manner of GCD. But when i try the below code it gave me weird scenario.

I testing the below code in Playground and Sync block executed 3times and the async block gave the NSException.

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let que = DispatchQueue.init(label: "testing")
        // Executed 3 times
        que.sync {
            for i in 0...10 {
                print(i)
            }
        }
        // Giving me NSException
        que.async {
            let label = UILabel()
            label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
            label.text = "Hello World!"
            label.textColor = .black

            view.addSubview(label)
            self.view = view
            print("Label Added to Text View")
        }
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Why it executes 3 times of sync block. and why there is an NSException error.

Upvotes: 1

Views: 943

Answers (1)

Vicente Garcia
Vicente Garcia

Reputation: 6370

Sync will stop the current thread until it has finished the task you are assigning to it.

Async will continue with the current thread and will execute the task in parallel or after the current thread.

Why it has unexpected behaviour?

That is because loadView() expects to have a UIView assigned to the view property after it has been executed, which you are doing it with async, which will be executed after loadView finishes.

The exception might be because you are not assigning a UIView on time or because you are handling the UI in your private Queue. UI should always be handled in the main thread.

Your variable que is a private queue, and because you didn't specify otherwise it is pointing to a background thread.

Editing your code like this might help you:

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let que = DispatchQueue.init(label: "testing")
        // Executed 3 times
        que.sync {
            for i in 0...10 {
                print(i)
            }
        }
        // Giving me NSException
        DispatchQueue.main.async {
            let label = UILabel()
            label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
            label.text = "Hello World!"
            label.textColor = .black

            view.addSubview(label)

            print("Label Added to Text View")
        }
        self.view = view
    }
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Upvotes: 2

Related Questions