在后台线程上的NSBlockOperation之后立即在主线程上运行一个块

时间:2015-06-26 20:51:06

标签: multithreading macos swift cocoa grand-central-dispatch

在我的项目中,我使用NSBlockOperation在后​​台线程上运行操作:

var operationQueue = NSOperationQueue()
var iop = NSBlockOperation(block: { self.reloadSize() /*calculation...*/ })
operationQueue.addOperation(iop)

在后台线程中的计算完成后,我需要在NSTableView上调用:table.reloadData()。我会在同一个线程中执行此操作,但是,由于自动布局问题,必须在主线程上重新加载表。如何跨两个线程完成这种异步关系?

2 个答案:

答案 0 :(得分:6)

两种可能的方法:

  1. 从块内部重新加载表:

    let operationQueue = NSOperationQueue()
    let operation = NSBlockOperation() {
        self.reloadSize()
        ...
        dispatch_async(dispatch_get_main_queue()) { // or you can use NSOperationQueue.mainQueue().addOperationWithBlock()
            self.table.reloadData()
        }
    }
    operationQueue.addOperation(operation)
    

    或只使用addOperationWithBlock

    let operationQueue = NSOperationQueue()
    operationQueue.addOperationWithBlock() {
        self.reloadSize()
        ...
        dispatch_async(dispatch_get_main_queue()) { // or you can use NSOperationQueue.mainQueue().addOperationWithBlock()
            self.table.reloadData()
        }
    }
    
  2. 根据以下内容创建一个新操作:

    let operationQueue = NSOperationQueue()
    
    let operation = NSBlockOperation() {
        self.reloadSize()
        ...
    }
    
    let completionOperation = NSBlockOperation() {
        self.table.reloadData()
    }
    
    completionOperation.addDependency(operation)
    
    operationQueue.addOperation(operation)
    NSOperationQueue.mainQueue().addOperation(completionOperation)
    
  3. 就个人而言,我通常倾向于第一种方法,尽管后一种方法在更复杂的情况下可能有用(例如,完成操作取决于许多其他操作)。

答案 1 :(得分:0)

尝试调用CFRunLoopRun()。 它应该在当前队列中运行。

如果您的操作在主队列上运行,则当前队列将成为主队列,并且操作将成功运行