【发布时间】:2023-03-18 22:35:01
【问题描述】:
我正在开发使用 OperationQueue 的 iOS 应用程序。我创建了 2 个操作。 Operation2 依赖于 Operation1 的完成。Operation2 如果正在运行,则需要等到 Operation 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
我在这里有什么遗漏吗?
【问题讨论】:
-
不确定我是否理解您的问题。您在问题的第 2 行中写到 operation2 可以在 operation1 正在进行或完成后开始。这是一个错字吗,因为如果您添加依赖项,它将等到 operation1 完成。为什么在将
codeToRun添加到队列后设置它。需要在将其添加到队列之前完成。 -
你的操作的这个实现是从某个地方复制过来的吗?您的代码存在许多问题。能否请您阅读操作文档。
-
codeToRun 在添加到队列之前设置。已更正。
-
您希望在第一次操作完成后开始第二次操作吗?如果是这样,您可以编辑问题的第二行吗?
-
更正谢谢
标签: swift concurrency nsoperationqueue nsoperation operation