Я работаю над приложением iOS, где использую OperationQueue. Я создал 2 операции. Операция 2 зависит от завершения операции 1. Операция 2 должна дождаться завершения операции 1, если она выполняется. Если операция 1 не выполняется, то операция 2 должна начаться немедленно.
Он не работает должным образом, поэтому я тестирую его на игровой площадке.
class MyManager {
var operationQueue: OperationQueue?
var operation1: MyOperation? = nil
var operation2: MyOperation? = nil
typealias completion = (_ serverError: String?) -> Void
func talkWithServer(completion: completion?) {
completion?("competed!")
}
func doOperation1() {
cancelProcess()
setup()
guard let operation1 = self.operation1 else { return }
operation1.codeToRun = {
print("operation1 started")
self.talkWithServer(completion: { (completion) in
print("operation1 completed")
operation1.markAsFinished()
})
}
operationQueue?.addOperation(operation1)
}
func doOperation2() {
self.operation2 = MyOperation()
guard let operation2 = self.operation2 else { return }
operation2.codeToRun = {
print("operation2 started")
self.talkWithServer(completion: { (completion) in
print("operation2 completed")
operation2.markAsFinished()
})
}
if let operation1 = self.operation1 {
if operation1.isExecuting {
operation2.addDependency(operation1)
operation1.completionBlock = {
print("operation1.completionBlock")
self.operationQueue?.addOperation(operation2)
}
}
} else {
operationQueue?.addOperation(operation2)
}
}
func cancelProcess() {
print("cancelAllOperations")
operationQueue?.cancelAllOperations()
}
func setup() {
print("setup Called")
operationQueue?.cancelAllOperations()
operationQueue = OperationQueue()
operation1 = MyOperation()
operation2 = MyOperation()
}
}
class MyOperation: Operation {
var codeToRun: (()->Void)?
var _executing = false
var _finished = false
override internal(set) var isExecuting: Bool {
get {
return _executing
}
set {
_executing = newValue
}
}
override internal(set) var isFinished: Bool {
get {
return _finished
}
set {
_finished = newValue
}
}
override var isAsynchronous: Bool {
return true
}
override func start() {
isExecuting = true
isFinished = false
if let closure = self.codeToRun {
closure()
}
}
func markAsFinished() {
self.isExecuting = false
self.isFinished = true
completionBlock?()
}
}
let manager = MyManager()
manager.doOperation1()
manager.doOperation2()
я получаю результат
cancelAllOperations
setup Called
operation1 started
operation1 completed
operation1.completionBlock
Ожидается
cancelAllOperations
setup Called
operation1 started
operation1 completed
operation1.completionBlock
operation2 started
operation2 completed
Я что-то пропустил здесь?
codeToRun
после добавления в очередь. Это необходимо сделать перед добавлением в очередь. - person user1046037   schedule 03.02.2018maxConcurrentOperationCount
очереди операций значение 1, чтобы в любой момент времени могла выполняться только 1 операция. Затем, если операция 1 начинается первой, операция 2 должна ждать ее, но если операции 1 нет, операция 2 просто начнется. При этом операции будут выполняться в том порядке, в котором они были добавлены, и каждая из них ожидает завершения предыдущей. - person Upholder Of Truth   schedule 03.02.2018