NSOperationQueue addOperations waitUntilFinished

NSOperationQueue addOperations waitUntilFinished

您好,我正在使用 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)

使用此代码 none 的操作正在执行。当我尝试这样做时:

NSOperationQueue.mainQueue().maxConcurrentOperationCount = 1
NSOperationQueue.mainQueue().addOperation(oldify)
NSOperationQueue.mainQueue().addOperation(appendify)
NSOperationQueue.mainQueue().addOperation(nettoyify)

操作已执行,但顺序不正确。

有谁知道我做错了什么?我对 swift 越来越有信心,但对 NSOperations

完全陌生

几个问题:

  1. 您正在检查完成块处理程序的行为。正如 completionBlock 文档所说:

    The exact execution context for your completion block is not guaranteed but is typically a secondary thread. Therefore, you should not use this block to do any work that requires a very specific execution context.

    队列将自己管理操作,但不会管理它们的完成块(缺少确保操作在其 completionBlock 开始之前完成)。所以,最重要的是,不要对 (a) 当完成块是 运行,(b) 一个操作的 completionBlock 与其他操作或它们的 completionBlock 块等的关系做任何假设., 也不是 (c) 它们在哪个线程上执行。

  2. 操作通常按照它们被添加到队列中的顺序执行。但是,如果您添加一个操作数组,该文档不会正式保证它们按照它们在该数组中出现的顺序排队。因此,您可能希望一次添加一个操作。

  3. 话虽如此,文档继续警告我们:

    An operation queue executes its queued operation objects based on their priority and readiness. If all of the queued operation objects have the same priority and are ready to execute when they are put in the queue—that is, their isReady method returns YES—they are executed in the order in which they were submitted to the queue. However, you should never rely on queue semantics to ensure a specific execution order of operation objects. Changes in the readiness of an operation can change the resulting execution order. If you need operations to execute in a specific order, use operation-level dependencies as defined by the NSOperation class.

    要建立明确的依赖关系,您可以这样做:

    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)
    
  4. 顺便说一句,正如您将在上面看到的,您不应该将操作与 waitUntilFinished 一起添加到主队列中。随意将它们添加到不同的队列,但不要使用 waitUntilFinished 选项从串行队列分派回自身。