Skip to content

Instantly share code, notes, and snippets.

@jeandavid
Created February 8, 2020 20:13
Show Gist options
  • Save jeandavid/9fe6dda1a092653872583955d189ca98 to your computer and use it in GitHub Desktop.
Save jeandavid/9fe6dda1a092653872583955d189ca98 to your computer and use it in GitHub Desktop.
Asynchronous Operation
class AsyncOperation: Operation {
// Only required when you want to manually start an operation
// Ignored when an operation is added to a queue.
override var isAsynchronous: Bool { return true }
// This is not the OperationQueue!
// This is the queue we use to read and write the operation state in a safe thread way
private let queue = DispatchQueue(label: "async_operation_private_queue", attributes: .concurrent)
// State is accessed and modified in a thread safe and KVO compliant way.
private var _isExecuting: Bool = false
override private(set) var isExecuting: Bool {
get {
return queue.sync { () -> Bool in return _isExecuting }
}
set {
willChangeValue(forKey: "isExecuting")
queue.sync(flags: [.barrier]) { _isExecuting = newValue }
didChangeValue(forKey: "isExecuting")
}
}
private var _isFinished: Bool = false
override private(set) var isFinished: Bool {
get {
return queue.sync { () -> Bool in return _isFinished }
}
set {
willChangeValue(forKey: "isFinished")
queue.sync(flags: [.barrier]) { _isFinished = newValue }
didChangeValue(forKey: "isFinished")
}
}
override func start() {
guard !isCancelled else {
finish()
return
}
isFinished = false
isExecuting = true
main()
}
override func main() {
fatalError("Subclasses must override main without calling super.")
}
func finish() {
isExecuting = false
isFinished = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment