Reputation: 329
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
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