1

我在 iPad 上有一个功能,我需要依次运行 3 个步骤,比如说 task1、task2、task3。Task2 需要从服务器加载一些数据。所以我需要把task2放到一个单独的后台线程中。

- (IBAction)dbSizeButton:(id)sender {

    //Task1......

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

    dispatch_async(queue, ^{

        //Task2 .....which go to server and download some stuff and update database.

        dispatch_sync(dispatch_get_main_queue(), ^{
            //Task3, continue to work on UI
        });
    });
}   

但看起来正在发生的事情是应用程序经常在 Task2 启动时被杀死。我不确定究竟是为什么。我可以看到 Task2 确实在单独的线程中执行。所以我想知道,如果这不是这样做的方法,而不是使用 GCD,我是否可以在 Task2 结束时向主线程发送消息或通知,以便我可以启动 Task3?究竟该怎么做?

4

2 回答 2

5

问题仅仅是你使用dispatch_sync, 哪个块。这就是你被杀的原因。你几乎是对的。你想要的是:

// ... task 1 on main thread
dispatch_async(other_queue, ^{
    // ... task 2 in background thread
    dispatch_async(dispatch_get_main_queue(), ^{
        // ... task 3 on main thread
    });
});

这是退出主线程并重新启动的标准模式。这里的所有都是它的!

于 2012-10-26T03:57:39.440 回答
2

通过使用 NSOperation 和 NSOperationQueue 而不是 GCD,您想要实现的目标会更容易。它不会触发通知,但我相信它会做你想做的事。

如果我正确理解了您的问题,那么您当前正在主线程中运行 task1。Task2 稍后通过 task1 同时触发,但 task2 告诉 task3 调用 UI。所以换句话说,task2 和 task3依赖于 task1,对吧?

使用 NSOperations(操作是一段代码,可以是选择器或块,您可以在不同的线程中运行)和 NSOperationQueues,您可以在不到一分钟的时间内实现这些依赖关系。

//Assuming task1 is currently running.
NSOperationQueue *downloadAndUpdate; //Leaving out initialization details.

NSOperationBlock *task2; //Leavign out initialization details.
NSOperationBlock *task3;

//This is where it gets interesting. This will make sure task3 ONLY gets fired if task2 is finished executing.
[task3 addDependency:task2];

//Task3 could have the following code to update the main thread.

[[NSOperationQueue mainQueue] addOperation:myUIUpdatingTask];

这些 API 比 GCD 级别更高,我绝对建议您学习如何使用它们来创建更好的并发性。

这是帮助您开始使用这些 API的教程。

(披露:我是这篇文章的作者,但我保证我的目的不是为我的工作做广告。我写这个教程是因为我需要一种比 GCD 更好的并发处理方法,并最终学习了这个。我喜欢教我学到了什么)。

于 2012-10-26T02:42:27.003 回答