Awesome
GCDKit
GCDKit is Grand Central Dispatch simplified with Swift.
Introduction
GCDKit implements the following constructs. To see how they work, jump right to the Common Usage Patterns section below.
GCDQueue
: An abstraction of thedispatch_queue_*
API.GCDQueue
s are expressed asenum
s, because we typically only need to deal with these queue types:
public enum GCDQueue {
case Main
case UserInteractive
case UserInitiated
case Default
case Utility
case Background
case Custom(dispatch_queue_t) // serial or concurrent
}
GCDBlock
: A struct that abstracts iOS 8's newdispatch_block_*
family of APIs.GCDGroup
: An abstraction of thedispatch_group_*
API.GCDSemaphore
: An abstraction of thedispatch_semaphore_*
API.
Common Usage Patterns
Here are some common use cases and how you can write them using GCDKit.
Creating and initializing queues
With the iOS SDK:
let mainQueue = dispatch_get_main_queue()
let defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let customSerialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL)
let customConcurrentQueue = dispatch_queue_create("myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT)
With GCDKit:
let mainQueue: GCDQueue = .Main
let defaultQueue: GCDQueue = .Default
let customSerialQueue: GCDQueue = .createSerial("mySerialQueue")
let customConcurrentQueue: GCDQueue = .createConcurrent("myConcurrentQueue")
In addition, custom queues created with dispatch_queue_create(...)
typically target a default-priority global queue unless you use the dispatch_set_target_queue(...)
API. For example, to raise the priority level of a created queue with the current SDK:
let customConcurrentQueue = dispatch_queue_create("myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT)
dispatch_set_target_queue(customConcurrentQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0))
With GCDKit, you can immediately specify the target queue on creation:
let customConcurrentQueue: GCDQueue = .createConcurrent("myConcurrentQueue", targetQueue: .UserInteractive)
Submitting tasks to queues
With the iOS SDK:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// some heavy work...
dispatch_async(dispatch_get_main_queue()) {
// send results to UI
}
}
With GCDKit you can either start a task chain from GCDBlock.async(...)
:
GCDBlock.async(.Default) {
// some heavy work...
}.notify(.Main) {
// send results to UI
}
or directly from a specific GCDQueue
enum
value:
GCDQueue.Default.async {
// some heavy work...
}.notify(.Main) {
// send results to UI
}
You can chain .notify(...)
calls as much as needed.
Launching and reporting completion of a group of tasks
With the iOS SDK:
let dispatchGroup = dispatch_group_create()
dispatch_group_enter(dispatchGroup)
doSomeLongTaskWithCompletion {
dispatch_group_leave(dispatchGroup)
}
dispatch_group_async(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// do another long task
}
dispatch_group_async(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// do yet another long task
}
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue()) {
// report completion
}
With GCDKit you can still use the usual enter()
-leave()
pairs and you can chain async calls to the dispatch group:
let dispatchGroup = GCDGroup()
dispatchGroup.enter()
doSomeLongTaskWithCompletion {
dispatchGroup.leave()
}
dispatchGroup.async(.Default) {
// do another long task
}.async(.Default) {
// do yet another long task
}.notify(.Main) {
// report completion
}
Semaphores
With the iOS SDK:
let numberOfIterations: UInt = 10
let semaphore = dispatch_semaphore_create(Int(numberOfIterations))
dispatch_apply(numberOfIterations, dispatch_queue_create("myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT)) {
(iteration: UInt) -> Void in
// do work for iteration
dispatch_semaphore_signal(semaphore)
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
With GCDKit:
let numberOfIterations: UInt = 10
let semaphore = GCDSemaphore(numberOfIterations)
GCDQueue.createConcurrent("myConcurrentQueue").apply(numberOfIterations) {
(iteration: UInt) -> Void in
// do work for iteration
semaphore.signal()
}
semaphore.wait()
Contributions
Feel free to report any issues or send suggestions!
License
GCDKit is released under an MIT license. See the LICENSE file for more information