Skip to content

Instantly share code, notes, and snippets.

@dmitryshliugaev
Created April 5, 2019 11:40
Show Gist options
  • Save dmitryshliugaev/a29519c12c54b3abae99c40ed4cce45d to your computer and use it in GitHub Desktop.
Save dmitryshliugaev/a29519c12c54b3abae99c40ed4cce45d to your computer and use it in GitHub Desktop.
Asynchronous Operation for synchronous Queue
class AsynchronousOperation: Operation {
@objc private enum OperationState: Int {
case ready
case executing
case finished
}
private let stateQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".rw.state", attributes: .concurrent)
private var _state: OperationState = .ready
@objc private dynamic var state: OperationState {
get { return stateQueue.sync { _state } }
set { stateQueue.sync(flags: .barrier) { _state = newValue } }
}
// MARK: - Various `Operation` properties
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 }
// KVN for dependent properties
open override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
if ["isReady", "isFinished", "isExecuting"].contains(key) {
return [#keyPath(state)]
}
return super.keyPathsForValuesAffectingValue(forKey: key)
}
// Start
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 }
}
}
let queue = OperationQueue()
queue.name = name
queue.maxConcurrentOperationCount = 1
queue.addOperation(SomeAsyncOperation())
queue.addOperation(SomeAsyncOperation())
queue.addOperation(SomeAsyncOperation())
queue.observe(\.operationCount, options: [.new]) { [weak self] _, change in
if change.newValue! == 0 {
// finish queue
}
}
class SomeAsyncOperation: AsynchronousOperation {
override func main() {
finish() // call whe u finish task
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment