Objective C中的一个常见模式是在后台线程中运行一些代码,然后返回主线程进行UI调整。如果代码在主线程中开始,我会用这样的模式攻击它:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self someBackgroundTask];
dispatch_async(dispatch_get_main_queue(), ^{
[self someUITask];
});
});
然而,这似乎是一种非常笨重的方式,至少不是因为它创造了两种层次的嵌套,感觉不必要。有一个更好的方法吗?请注意,在此实例中,UI代码被视为依赖于后台任务完成,因此不能在第一次调度后删除它。
答案 0 :(得分:0)
从概念上讲,您需要在两个不同的线程上运行代码。所有UI操作必须在主线程上运行,并且阻塞操作需要在后台线程上运行。在绝对最小值,这将需要两行代码。
如你所说,GCD使这相当简单;我不确定任何语言都有更好的方法来处理这个核心问题。当然,块语法不好(http://fuckingblocksyntax.com);但核心基本面非常稳固。
如果嵌套困扰您,请尝试将所有UI代码移动到其他方法,并从第二个嵌套块调用该方法。您甚至可以创建一个接受'backgroundWork'选择器/块和'前景工作'选择器/块的方法。但是 - 我认为你在这种情况下执行的典型用户界面工作非常少,这使得额外的嵌套成为一个小麻烦而不是实际问题。
对于相互依赖的异步代码块,请查看PromiseKit甚至是Sequencer;两者都是补充Objective C主要弱点之一的良好选择(顺序执行多线程操作)。
我自己没有使用它,但据我所知,Facebook / Parse还发布了另一个名为BFTask的解决方案,它是Bolts框架的一部分:https://github.com/BoltsFramework/Bolts-iOS
(或者只是使用C#)
答案 1 :(得分:0)
将所有线程内容移动到someBackgroundTask:
[self someBackgroundTaskWithCompletion:^{
[self someUITask];
}];
然后在后台任务方法中执行dispatch_async()
内容。