TestsTested | ✗ |
LangLanguage | SwiftSwift |
License | MIT |
ReleasedLast Release | Jun 2015 |
SPMSupports SPM | ✗ |
Maintained by Mathew Huusko V.
Drag Do-[Swift version].swift into your project.
dispatch_sync
/dispatch_barrier_sync
with return values)dispatch_apply
with range version)dispatch_after
)dispatch_once
)dispatch_async
)Do! provides easy access to the main queue, global priority queues, as well as the global ‘quality of service’ queues available in OS X 10.10
and iOS 8.0
and later (with appropriate fallbacks in place).
Do.mainQueue // The "main" dispatch queue.
Do.highPriorityQueue // The global "high priority" dispatch queue.
Do.defaultQueue // The global "default" dispatch queue.
Do.lowPriorityQueue // The global "low priority" dispatch queue.
Do.backgroundQueue // The global "background" dispatch queue.
Do.userInteractiveQueue // The global "user interactive" (super high priority?) dispatch queue.
Do.userInitiatedQueue // The global "user initiated" (equivalent to "high priority") dispatch queue.
Do.utilityQueue // The global "utility" (equivalent to "low priority") dispatch queue.
Do! also provides a way to check whether you are currently dispatched on a specific queue by comparing labels (give your queues labels!).
if Do.isCurrentQueue(mainQueue) {
print("Hello from the main queue!")
}
Do! provides a wrapper around dispatch_sync
and dispatch_barrier_sync
that is succinct and deadlock safe (well, more deadlock safe – it uses Do.isCurrentQueue
to avoid this, but that only helps if you try to dispatch to the current queue, not one higher up in the dispatch tree).
Do.sync(someSerialQueue) {
print("Hello world!")
}
Do.barrierSync(someConcurrentQueue) {
print("Hello world!")
}
More importantly, Do! provides versions which returns values, which is perfect for synchronizing access to resources…
let resource: Resource = Do.sync(someSerialQueue) {
// .. heavy work that should happen serially...
return importantResource
}
let resource: Resource = Do.barrierSync(someConcurrentQueue) {
// .. heavy work that should block queue...
return importantResource
}
.. or even synchronizing properties.
class Variable {
private var _value: Any
var value: Any {
get { return barrierSync(someConcurrentQueue) { self._value } }
set { barrierSync(someConcurrentQueue) { self._value = newValue } }
}
}
Do! provides a wrapper around dispatch_apply
that is succinct and deadlock safe (again, more deadlock safe). If the targetted queue is the current dispatch queue (or nil), it reverts to a plain loop.
Do.loop(100, highPriorityQueue) { i in
print(i)
}
Do.loop(10) { i in
print(i)
}
Do! also provides a version which takes a range instead of an iterations count.
Do.loop(15..<55, highPriorityQueue) { i in
print(i)
}
Do! provides a wrapper around dispatch_after
that is succinct and defaults to the main queue…
Do.after(3.0) {
print("Hello world!")
}
Do.after(0.5, backgroundQueue) {
print("Hello world!")
}
.. as well as a version returning a block for cancellation of the scheduled dispatch.
let cancel = Do.afterCancel(10) {
print("Hello world!")
}
Do.after(2) {
cancel()
}
Do! provides a simple but powerful mechanism for dispatching async operations (which might have async/nested dispatches themselves) that can be limited to processing sequentially or N at a time.
static token = Do.ConcurrentToken() // store this somewhere!
// ...
for i in 0..<100 {
Do.concurrent(token, highPriorityQueue) { done in
// some heavy stuff...
done()
}
}
// the 100 operations will process one at a time...
static token = Do.ConcurrentToken(limit: 5)
for i in 0..<50 {
Do.concurrent(token, mainQueue) { done in
Do.after(0.5) {
done()
}
}
Do.concurrent(token, backgroundQueue) { done in
Do.after(1.0) {
done()
}
}
}
// the 100 operations (with different logic/queues) will process 5 at a time
Do! provides an uber-succinct wrapper around dispatch_once
(using hackery.. so beware, it works/is stable, but is not guaranteed to be the most performant solution).
Do.once {
print("Hello world!")
}
Do! also provides a version which stores the result of the initial dispatch, and simply returns the value on all subsequent dispatches (again, hackery).
for i in 0..<10 {
let message: String = Do.once {
print("Some lazy/heavy stuff that should only happen once ;)")
return "Hello world!"
}
print(message)
}
Do! provides an uber-succinct way to dispatch a block a max of once per N seconds (again, hackery).
Do.throttle(3.4) {
print("Hello world!")
}
Do.throttle(0.5, backgroundQueue) {
print("Hello world!")
}
Do! provides a wrapper around dispatch_async
that is succinct, and convenient. That’s it really, though. For added features (e.g. chaining) I recommend Async by duemunk.
Do.async(userInitiatedQueue) { ... }
Do.barrierAsync(userInitiatedQueue) { ... }
let group = dispatch_group_create()
Do.groupAsync(group, userInitiatedQueue) { ... }
Do.barrierGroupAsync(group, userInitiatedQueue) { ... }
Do.main { ... }
Do.background { ... }
Do.userInteractive { ... }
Do.userInitiated { ... }