Created
March 10, 2019 17:19
-
-
Save esphynox/82c8efb98c6e0b9abf16290fc960cb8e to your computer and use it in GitHub Desktop.
This file contains hidden or 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 class AsyncOperation: Operation { | |
@objc enum State: Int { | |
case ready | |
case executing | |
case finished | |
} | |
private let stateQueue = DispatchQueue(label: "\(Bundle.main.bundleIdentifier!).AsyncOperation.state", attributes: .concurrent) | |
private var _state: State = .ready | |
@objc dynamic var state: State { | |
get { | |
return stateQueue.sync { | |
_state | |
} | |
} | |
set { | |
stateQueue.sync(flags: .barrier) { | |
_state = newValue | |
} | |
} | |
} | |
open override var isReady: Bool { | |
return state == .ready && super.isReady | |
} | |
public final override var isExecuting: Bool { | |
return state == .executing | |
} | |
public final 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 final override func start() { | |
if isCancelled { | |
finish() | |
return | |
} | |
state = .executing | |
main() | |
} | |
open override func main() { | |
fatalError("Subclasses must implement `main`.") | |
} | |
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