我有这个代码将NSOperation
实例添加到队列
let operation = NSBlockOperation()
operation.addExecutionBlock({
self.asyncMethod() { (result, error) in
if operation.cancelled {
return
}
// etc
}
})
operationQueue.addOperation(operation)
当用户离开触发上述代码的视图时,我取消操作
operationQueue.cancelAllOperations()
在测试取消时,我100%确定在异步方法返回之前执行取消,所以我希望operation.cancelled
为真。不幸的是,这种情况并没有发生,我无法理解为什么
我正在viewWillDisappear
修改
asyncMethod
包含在不同线程中运行的网络操作。这就是回调存在的原因:处理网络操作返回。网络操作在类层次结构深入执行,但我想在根级别处理NSOperations。
答案 0 :(得分:3)
调用此对象的cancel方法设置此值 财产到是。一旦取消,操作必须移至完成 状态。
取消操作不会主动停止接收者的代码 执行。操作对象负责调用此方法 如果方法返回YES,则定期并自行停止。
在执行任何操作之前,您应该始终检查此属性的值 努力完成操作的任务,这通常意味着 在自定义主方法的开头检查它。它是 可以在开始执行之前取消操作 或在执行期间的任何时间。因此,检查值 主要方法的开头(并在整个过程中定期开始) 方法)让您在操作时尽快退出 取消。
import Foundation
let operation1 = NSBlockOperation()
let operation2 = NSBlockOperation()
let queue = NSOperationQueue()
operation1.addExecutionBlock { () -> Void in
repeat {
usleep(10000)
print(".", terminator: "")
} while !operation1.cancelled
}
operation2.addExecutionBlock { () -> Void in
repeat {
usleep(15000)
print("-", terminator: "")
} while !operation2.cancelled
}
queue.addOperation(operation1)
queue.addOperation(operation2)
sleep(1)
queue.cancelAllOperations()
在游乐场尝试这个简单的例子。
如果运行另一个异步代码非常重要,请尝试使用
operation.addExecutionBlock({
if operation.cancelled {
return
}
self.asyncMethod() { (result, error) in
// etc
}
})
答案 1 :(得分:2)
let operationQueue = OperationQueue()
operationQueue.qualityOfService = .background
let ob1 = BlockOperation {
print("ExecutionBlock 1. Executed!")
}
let ob2 = BlockOperation {
print("ExecutionBlock 2. Executed!")
}
operationQueue.addOperation(ob1)
operationQueue.addOperation(ob2)
ob1.cancel()
// ExecutionBlock 2. Executed!
let operationQueue = NSOperationQueue()
operationQueue.qualityOfService = .Background
let ob1 = NSBlockOperation()
ob1.addExecutionBlock {
print("ExecutionBlock 1. Executed!")
}
let ob2 = NSBlockOperation()
ob2.addExecutionBlock {
print("ExecutionBlock 2. Executed!")
}
operationQueue.addOperation(ob1)
operationQueue.addOperation(ob2)
ob1.cancel()
// ExecutionBlock 2. Executed!
答案 2 :(得分:1)
操作不会等待asyncMethod
完成。因此,如果将其添加到队列,它会立即返回。这是因为您将异步网络操作包装在异步NSOperation
中。
NSOperation旨在提供更高级的异步处理,而不仅仅是调用performSelectorInBackground
。这意味着NSOperation
用于在后台运行复杂且长时间运行的操作,而不是阻塞主线程。在这里可以找到一篇通常使用的NSOperation
的好文章:
http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues
对于您的特定用例,在此处使用NSOperation是没有意义的,而应该取消正在运行的网络请求。
答案 3 :(得分:1)
将异步函数放入具有NSBlockOperation
的块中是没有意义的。您可能想要的是NSOperation
的正确子类作为执行异步工作负载的并发操作。然而,正确地对NSOperation
进行子类化并不是那么容易。
您可以在此处查看reusable subclass for NSOperation以获取示例实现。
答案 4 :(得分:0)
我不是100%确定你在寻找什么,但也许你需要的是将操作作为参数传递到asyncMethod()
并测试那里的取消状态?
operation.addExecutionBlock({
asyncMethod(operation) { (result, error) in
// Result code
}
})
operationQueue.addOperation(operation)
func asyncMethod(operation: NSBlockOperation, fun: ((Any, Any)->Void)) {
// Do stuff...
if operation.cancelled {
// Do something...
return // <- Or whatever makes senes
}
}