I created a basic background thread class in swift to replace the ugliness of:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
// background thread code
dispatch_async(dispatch_get_main_queue()) { () -> Void in
// done, back to main thread
}
}
with the expressiveness of:
Background { () -> () in
// background code
}.afterInterval(3) { () -> () in
// main thread, run after interval IF not done
}.completion { () -> () in
// done, main thread
}
afterInterval
and completion
are optional and interchangeable.
How reliable is this approach? Can we ever return from init(task)
before completion
is added, using the dot syntax? I have tested to my abilities and it seems rather bulletproof, but am wondering about the thoughts here.
class Background {
private var done = false {
didSet {
if done {
taskInterval = nil
dispatch_async(dispatch_get_main_queue()) { () -> Void in
completion?()
}
}
}
}
private var taskInterval: (() -> ())?
private var completion: (() -> ())?
init(task: () -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
task()
self.done = true
}
}
func afterInterval(interval: NSTimeInterval, closure: () -> ()) -> Background {
taskInterval = closure
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(interval * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) { [weak self] in
self?.taskInterval?()
}
return self
}
func completion(closure: () -> ()) -> Background {
completion = closure
return self
}
}