我在iOS应用程序上工作,我正在使用OperationQueue。我创建了2个操作。 Operation2取决于Operation1.Operation2的完成,需要等到操作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
我在这里错过了什么吗?
答案 0 :(得分:1)
我一直在看你的代码。我找到了一些东西:
manager.doOperation1()
manager.doOperation2()
这并不意味着operation2在operation1完成后运行,如果你想这样做,你可以为operation1添加一个完成闭包。
致电
doOperation2()
在这个函数中似乎代码从未执行过:
guard let operation2 = self.operation2 else { return }
您似乎想要创建自己的车轮。我建议你学习一些关于GCD的知识,你可以在这里找到资源:
答案 1 :(得分:0)
有几件事:
KVO
和isExecuting
isFinished
doOperation2
operation2
即使在operation1
完成之前已添加到队列中,也无法启动。MyOperation
下面不是实现doOperation2
的理想方法,但会从代码中消除一些混乱。我将根据下面提到的设计部分留给你实现整个事情。
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")
})
}
operationQueue?.addOperation(operation2)
}
MyOperation
似乎是通用的,您似乎在您称之为的地方进行大部分实际工作MyOperation
以完成实际工作。FetchData()
是一个操作,ParseData()
是另一个操作。 答案 2 :(得分:0)
您需要做的就是添加对依赖操作的依赖。
let queue = OperationQueue()
let operation1 = BlockOperation(block: { [weak self] in
self?.doOperation1()
})
let operation2 = BlockOperation(block: { [weak self] in
self?.doOperation2()
})
operation1.addDependency(operation2) // THIS IS THE KEY CODE IN YOUR CASE
queue.addOperation(operation1)
queue.addOperation(operation2)
希望这可以帮助您解决依赖性问题。