Created
April 6, 2016 17:27
-
-
Save shu223/d1c5725ee4fd4f8fedf88928b90da5bd to your computer and use it in GitHub Desktop.
Async https://github.com/duemunk/Async の `background` と `main` をチェーン実行するために必要な最小限のコードを抜き出したもの
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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