如何在Xcode中向主线程发送消息或通知?

时间:2012-10-26 02:27:40

标签: iphone xcode grand-central-dispatch

我在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吗?怎么做到这一点?

2 个答案:

答案 0 :(得分: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
    });
});

这是下线主线程并重新开始的标准模式。这就是它的全部!

答案 1 :(得分: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更高级,我绝对建议您学习如何使用它们来创建更好的并发性。

Here's a tutorial帮助您开始使用这些API。

(披露:我是这篇文章的作者,但我保证我的意图不是宣传我的工作。我写这篇教程是因为我需要一种更好的方法来做并发而不是GCD并最终学习这个我喜欢教我学到的东西。