我在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吗?怎么做到这一点?
答案 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并最终学习这个我喜欢教我学到的东西。