我在我的应用程序中使用Grand Central Dispatch以便在后台运行方法。该方法基于用户的输入计算一些数学数据,并且需要一些时间来完成。请记住,它没有使用互联网。
每当主视图加载时,我都会运行此背景“compute”方法(它是一个调度队列)。问题是如果用户在后台运行方法时切换应用程序中的视图,应用程序崩溃。
当用户切换视图时,有没有办法“取消”队列/停止运行代码块?另一种思考方式是查看iPhone Weather.app。当天气加载时,它会在后台下载数据,并在下载时按下角落中的小信息按钮不会使应用程序崩溃。
谢谢!
queue = dispatch_queue_create("com.mycompany.myqueue", 0);
dispatch_async(queue, ^{
//make some complicated calculations
});
答案 0 :(得分:2)
一旦块开始执行,暂停队列本身将无法帮助您。但是您可以使用__block限定符定义一个名为'cancel'的BOOL,然后在计算的适当阶段(在每次迭代或其他段),您可以在继续之前检查'cancel'是否为NO。
答案 1 :(得分:1)
其他人已经提出了设置共享取消标志的简单技术(这是应该如何取消,因为GCD不支持隐式取消)但是当用户切换视图时应用程序崩溃的事实也意味着有工作在块内完成,特别是与UI状态相关联。当用户切换时,你的后台块被这个致命的混淆这一事实表明你真的需要在某种程度上重构代码。您应该已经在主队列上调度所有AppKit或UIKit调用,因为它们不能用于其他任何调用,因此必须有一个对象引用在用户切换视图时发生更改,您只需要考虑在检查之后立即取消操作的情况,并且您仍在将用户交互带到最终粘性端。 GCD从你的肩膀上承担了很多多线程代码的负担,但它不是解决并发问题的灵丹妙药,比如共享对象引用等等 - 那些仍然存在并且是难题,GCD只是让它更容易修复它们(比如允许你为代码中的每个共享/竞争对象创建一个相应的串行队列,并重构你的setter / getter方法以将该队列用作并发障碍。)