Skip to content

Instantly share code, notes, and snippets.

@hishma
Created March 26, 2019 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hishma/8608b02b39b0df6a22181a5f3a1918f1 to your computer and use it in GitHub Desktop.
Save hishma/8608b02b39b0df6a22181a5f3a1918f1 to your computer and use it in GitHub Desktop.
public class AsynchronousOperation: Operation {
@objc private enum State: Int {
case ready, executing, finished
}
private var _state = State.ready
private let stateQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".op.state", attributes: .concurrent)
@objc private dynamic var state: State {
get { return stateQueue.sync { _state } }
set { stateQueue.sync(flags: .barrier) { _state = newValue } }
}
public override var isAsynchronous: Bool { return true }
open override var isReady: Bool {
return super.isReady && state == .ready
}
public override var isExecuting: Bool {
return state == .executing
}
public override var isFinished: Bool {
return state == .finished
}
open override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
if ["isReady", "isFinished", "isExecuting"].contains(key) {
return [#keyPath(state)]
}
return super.keyPathsForValuesAffectingValue(forKey: key)
}
public override func start() {
if isCancelled {
finish()
return
}
self.state = .executing
main()
}
open override func main() {
fatalError("Implement in sublcass to perform task")
}
public final func finish() {
if isExecuting {
state = .finished
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment