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

3

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

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

在后台线程完成计算后,我需要调用table.reloadData()来重新加载NSTableView。虽然我可以在同一线程中执行此操作,但由于自动布局问题,必须在主线程上重新加载表格。我该如何在两个线程之间实现异步关系?

2个回答

7

两种可能的方法:

  1. Dispatch the reloading of the table from inside the block:

    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)
    

    or just use 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. Create a new operation dependent upon this one:

    let operationQueue = NSOperationQueue()
    
    let operation = NSBlockOperation() {
        self.reloadSize()
        ...
    }
    
    let completionOperation = NSBlockOperation() {
        self.table.reloadData()
    }
    
    completionOperation.addDependency(operation)
    
    operationQueue.addOperation(operation)
    NSOperationQueue.mainQueue().addOperation(completionOperation)
    

个人而言,我通常倾向于第一种方法,尽管后一种方法在更复杂的情况下也很有用(例如,完成操作依赖于许多其他操作)。


太好了!感谢您提供备选方案。 - Jonathan H.

-1
尝试调用CFRunLoopRun()。 它应该在当前队列中运行。
如果您的操作在主队列上运行,当前队列将是主队列,并且操作将成功地在其上运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接