您好我正在使用Swift构建应用程序。我需要按特定顺序处理通知。因此我尝试使用addOperations waitUntilFinished。
这是我做的:
let oldify = NSOperation()
oldify.completionBlock = {
println("oldify")
}
let appendify = NSOperation()
appendify.completionBlock = {
println("appendify")
}
let nettoyify = NSOperation()
nettoyify.completionBlock = {
println("nettoyify")
}
NSOperationQueue.mainQueue().maxConcurrentOperationCount = 1
NSOperationQueue.mainQueue().addOperations([oldify, appendify, nettoyify], waitUntilFinished: true)
使用此代码,没有任何操作正在执行。当我尝试这样做时:
NSOperationQueue.mainQueue().maxConcurrentOperationCount = 1
NSOperationQueue.mainQueue().addOperation(oldify)
NSOperationQueue.mainQueue().addOperation(appendify)
NSOperationQueue.mainQueue().addOperation(nettoyify)
操作已执行但顺序不正确。
有谁知道我做错了什么?我对NSOperations迅速而又全新地充满信心
答案 0 :(得分:5)
有几个问题:
您正在检查完成块处理程序的行为。正如completionBlock
文档所说:
无法保证完成块的确切执行上下文,但通常是辅助线程。因此,您不应该使用此块来执行任何需要非常特定的执行上下文的工作。
队列将自己管理操作,但不管理它们的完成块(缺少确保操作在completionBlock
启动之前完成)。因此,最重要的是,不要对(a)运行完成块的时间,(b)一个操作completionBlock
与其他操作或其completionBlock
块等的关系进行任何假设,也不( c)执行哪个线程。
操作通常按照添加到队列的顺序执行。但是,如果添加一组操作,则文档不会正式保证它们按照它们在该数组中出现的顺序排队。因此,您可能希望一次添加一个操作。
话虽如此,文档继续警告我们:
操作队列根据其优先级和准备情况执行排队的操作对象。如果所有排队的操作对象具有相同的优先级并且在将它们放入队列时准备好执行 - 也就是说,它们的
isReady
方法返回YES
- 它们按照它们的顺序执行被提交到队列。但是,您不应该依赖队列语义来确保操作对象的特定执行顺序。操作就绪的更改可以更改生成的执行顺序。如果需要按特定顺序执行操作,请使用NSOperation
类定义的操作级依赖项。
要建立显式依赖关系,您可以执行以下操作:
let oldify = NSBlockOperation() {
NSLog("oldify")
}
oldify.completionBlock = {
NSLog("oldify completion")
}
let appendify = NSBlockOperation() {
NSLog("appendify")
}
appendify.completionBlock = {
NSLog("appendify completion")
}
appendify.addDependency(oldify)
let nettoyify = NSBlockOperation() {
NSLog("nettoyify")
}
nettoyify.completionBlock = {
NSLog("nettoyify completion")
}
nettoyify.addDependency(appendify)
let queue = NSOperationQueue()
queue.addOperations([oldify, appendify, nettoyify], waitUntilFinished: false)
顺便说一句,正如您将在上面看到的那样,您不应该将操作与waitUntilFinished
一起添加到主队列中。可以随意将它们添加到不同的队列中,但不要使用waitUntilFinished
选项从串行队列发送回自身。