Skip to content

Instantly share code, notes, and snippets.

@shu223
Created April 6, 2016 17:27
Show Gist options
  • Save shu223/d1c5725ee4fd4f8fedf88928b90da5bd to your computer and use it in GitHub Desktop.
Save shu223/d1c5725ee4fd4f8fedf88928b90da5bd to your computer and use it in GitHub Desktop.
Async https://github.com/duemunk/Async の `background` と `main` をチェーン実行するために必要な最小限のコードを抜き出したもの
public struct Async {
// MARK: - Private properties and init
/**
Private property to hold internally on to a `dispatch_block_t`
*/
private let block: dispatch_block_t
/**
Private init that takes a `dispatch_block_t`
*/
private init(_ block: dispatch_block_t) {
self.block = block
}
// MARK: - Private static methods
private static func async(seconds: Double? = nil, block chainingBlock: dispatch_block_t, queue: dispatch_queue_t) -> Async {
if let seconds = seconds {
return asyncAfter(seconds, block: chainingBlock, queue: queue)
}
return asyncNow(chainingBlock, queue: queue)
}
private static func asyncNow(block: dispatch_block_t, queue: dispatch_queue_t) -> Async {
let _block = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, block)
dispatch_async(queue, _block)
return Async(_block)
}
private static func asyncAfter(seconds: Double, block: dispatch_block_t, queue: dispatch_queue_t) -> Async {
let nanoSeconds = Int64(seconds * Double(NSEC_PER_SEC))
let time = dispatch_time(DISPATCH_TIME_NOW, nanoSeconds)
return at(time, block: block, queue: queue)
}
private static func at(time: dispatch_time_t, block: dispatch_block_t, queue: dispatch_queue_t) -> Async {
let _block = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, block)
dispatch_after(time, queue, _block)
return Async(_block)
}
// MARK: - Static methods
public func main(after after: Double? = nil, chainingBlock: dispatch_block_t) -> Async {
return chain(after, block: chainingBlock, queue: GCD.mainQueue())
}
public static func background(after after: Double? = nil, block: dispatch_block_t) -> Async {
return Async.async(after, block: block, queue: GCD.backgroundQueue())
}
// MARK: Private instance methods
private func chain(seconds: Double? = nil, block chainingBlock: dispatch_block_t, queue: dispatch_queue_t) -> Async {
if let seconds = seconds {
return chainAfter(seconds, block: chainingBlock, queue: queue)
}
return chainNow(block: chainingBlock, queue: queue)
}
private func chainNow(block chainingBlock: dispatch_block_t, queue: dispatch_queue_t) -> Async {
let _chainingBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, chainingBlock)
dispatch_block_notify(block, queue, _chainingBlock)
return Async(_chainingBlock)
}
private func chainAfter(seconds: Double, block chainingBlock: dispatch_block_t, queue: dispatch_queue_t) -> Async {
let _chainingBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, chainingBlock)
let chainingWrapperBlock: dispatch_block_t = {
let nanoSeconds = Int64(seconds * Double(NSEC_PER_SEC))
let time = dispatch_time(DISPATCH_TIME_NOW, nanoSeconds)
dispatch_after(time, queue, _chainingBlock)
}
let _chainingWrapperBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, chainingWrapperBlock)
dispatch_block_notify(self.block, queue, _chainingWrapperBlock)
return Async(_chainingBlock)
}
}
private struct GCD {
static func mainQueue() -> dispatch_queue_t {
return dispatch_get_main_queue()
}
static func backgroundQueue() -> dispatch_queue_t {
return dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment