我在我的可可应用程序中有2个窗口。主窗口打开一个子窗口。在子窗口上点击OK,我在主窗体上调用一个确认按钮,这将显示在子窗口上单击确定按钮。实现后台工作 - Obj C /可可
现在,我需要在主窗口上“在后台”运行一个长时间运行的进程,以便窗口不会变得没有响应。我也有进度条,应该显示这个长时间运行过程的进度。
请让我知道,达到此目的的最佳方法是什么。
我在我的可可应用程序中有2个窗口。主窗口打开一个子窗口。在子窗口上点击OK,我在主窗体上调用一个确认按钮,这将显示在子窗口上单击确定按钮。实现后台工作 - Obj C /可可
现在,我需要在主窗口上“在后台”运行一个长时间运行的进程,以便窗口不会变得没有响应。我也有进度条,应该显示这个长时间运行过程的进度。
请让我知道,达到此目的的最佳方法是什么。
您应该从Apple的Concurrency Programming Guide开始。
特别是关于NSOperationQueue的部分。
您可以使用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有时更容易。这取决于你想要做什么。
Apple建议您始终使用API的最高级别抽象,除非您需要仅由较低级别的API提供的特定行为。所以你应该真的推荐NSOperationQueue – Tim
@Jeff:'NSOperationQueue'是一个整洁的类,但GCD同样是多功能的,我认为它也更容易跳到。 'NSOperationQueue'需要一些练习,有时会以我的经验为新用户拉头发。 – SevenBits
@SevenBits有趣的是你有相同的经历。我还发现NSOperation更难推理。尽管NSOperation较高,但它的年龄较大,所以我认为GCD设计得更好是有道理的,因为它是一种更新的API,具有事后的好处。 –