2014-02-14 59 views
1

我在我的可可应用程序中有2个窗口。主窗口打开一个子窗口。在子窗口上点击OK,我在主窗体上调用一个确认按钮,这将显示在子窗口上单击确定按钮。实现后台工作 - Obj C /可可

现在,我需要在主窗口上“在后台”运行一个长时间运行的进程,以便窗口不会变得没有响应。我也有进度条,应该显示这个长时间运行过程的进度。

请让我知道,达到此目的的最佳方法是什么。

回答

4

您可以使用Grand Central Dispatch为此。首先创建一个调度队列,它将包含您想要在另一个线程上执行的操作。每个操作都表示为一个Objective-C块(关闭)。

首先你得到一个队列来把你想在另一个线程上运行的任务。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

然后你把一个块表示要在这个队列中所做的工作:

dispatch_async(queue, ^{ 
    // this happens on separate thread 
    NSImage *image = produceImageFromSomeReallySlowOperation() 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     // this happens on main thread 
     [myView setImage:image]; 
    }); 

}); 

dispatch_get_main_queue()函数会返回一个用于操作的主线程(在GUI是队列执行)。这意味着[myView setImage:image]将在主线程上执行。您可以在此处放置进度条的更新。只需在主队列上调度即可更新算法中每个点的进度,这样做有意义。

所有这些也可以使用NSOperation来执行,它为相同的功能提供更高级的Objective-C接口。但直接使用GCD有时更容易。这取决于你想要做什么。

+1

Apple建议您始终使用API​​的最高级别抽象,除非您需要仅由较低级别的API提供的特定行为。所以你应该真的推荐NSOperationQueue – Tim

+1

@Jeff:'NSOperationQueue'是一个整洁的类,但GCD同样是多功能的,我认为它也更容易跳到。 'NSOperationQueue'需要一些练习,有时会以我的经验为新用户拉头发。 – SevenBits

+0

@SevenBits有趣的是你有相同的经历。我还发现NSOperation更难推理。尽管NSOperation较高,但它的年龄较大,所以我认为GCD设计得更好是有道理的,因为它是一种更新的API,具有事后的好处。 –