Created
February 8, 2020 20:13
-
-
Save jeandavid/9fe6dda1a092653872583955d189ca98 to your computer and use it in GitHub Desktop.
Asynchronous Operation
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
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