Utilizing GCD in IOS Application Development
GCD?
- An Acronym for Grand Central Dispatch
- Multi-tasking in multi-core -> paralell
- Multi-tasking in a single-core -> concurrent
- 2 ways to do Multi-tasking in IOS -> NSOperationQueue / GCD
- GCD handles difficulties without taking complex problems into account.
- queue: a bunch of code. FIFO
- work item: a block of code, can be reused. execution in a queue follows FIFO
- View, Core Animation, and other UIKit classes -> main thread
- Lengthy tasks -> background thread asynchronously
- At launch time -> no additional work on main thread
GCD Usage
Sync vs Async
Sync : Sync with Main Thread. Main thread waits till the work item on the background queue finishes its work.
Async : Async with Main Thread. Main thread does not wait and finishes first (because it always have higher priority than others)
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
syncTest()
}
func syncTest(){
let queue = DispatchQueue(label:"syncTestQueue")
queue.sync {
// change this to queue.async and see what happens
for i in 0..<10{
print("background", i)
}
}
for i in 100..<110{
print("main", i)
}
}
}
QoS
- QoS, Quality of Service, decides the queue’s priority
- a task that has higher priority than others finishes earlier.
- (prioirity order,) userInteractive > userInitiated > default > utility > background > unspecified
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
qosTest()
}
func qosTest(){
let queue1 = DispatchQueue(label:"qosTestQueue1", qos: DispatchQos.userInitiated)
let queue2 = DispatchQueue(label:"qosTestQueue2", qos: DispatchQos.utility)
queue1.async {
for i in 0..<10{
print("userInitiated", i)
}
}
queue2.async {
for i in 100..<110{
print("utility", i)
}
}
}
}
Concurrent Queues
- a queue that has more than one work item, it can execute items in either concurrent or serial(by default).
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
concTest()
}
func concTest(){
let queue = DispatchQueue(label:"concTestQueue", qos: DispatchQos.userInitiated, attributes: .concurrent)
queue.async {
for i in 0..<10{
print("work item 1", i)
}
}
queue.async {
for i in 100..<110{
print("work item 2", i)
}
}
}
}
Initially inactive Queus
- a queue that is not active until the user activates the queue.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
initInactTest()
if let queue = initInactQueue{
queue.activate()
}
}
var initInactQueue:DispatchQueue!
func initInactTest(){
let queue = DispatchQueue(label:"initInactTestQueue", qos: DispatchQos.userInitiated, attributes: .initiallyInactive)
// since this queue is not activated until function initInactTest exits,
// we need to use class property to get the queue.
initInactQueue = queue
queue.async {
for i in 0..<10{
print("work item 1", i)
}
}
queue.async {
for i in 100..<110{
print("work item 2", i)
}
}
}
}
Queue with delay
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
queueWithDelayTest()
}
}
func queueWithDelayTest(){
queue = DispatchQueue(label:"queueWithDelayTest", qos:.userInitiated)
print(Date())
let timeInterval: DispatchTimeInterval = .seconds(2)
queue.asyncAfter(deadline: .now() + timeInterval){
//timeInterval can be a double
print(Date())
}
}
}
Main and Global Queues
- Main queue : Running for UI
- Global Queues : Background queues
let globalQueue = DispatchQueue.global()
globalQueue.async {
for i in 0..<10{
print("global queue 1", i)
}
}
- Accessing Main queue from any other queue
DispatchQueue.main.async {
}
Work Item
- work item: a block of code
func useWorkItem() {
var value = 10
let workItem = DispatchWorkItem {
value += 5
}
workItem.perform() // performed in the main thread
let queue = DispatchQueue.global(qos: .utility)
queue.async(execute: workItem) // performed in the background queue
workItem.notify(queue: DispatchQueue.main) {
print("value = ", value) //invoked when
}
}
modified resources from: https://www.appcoda.com/grand-central-dispatch/
Written on January 27, 2018