ios - 返回时取消 GCD 异步任务

标签 ios asynchronous uinavigationcontroller block grand-central-dispatch

我的 iOS 应用程序的 View Controller 中有一个运行时间相对较长的任务(5-10 秒)。它通过 GCD 在后台异步运行。用户可以在此任务期间进行 UI 操作,因此他还可以按后退按钮导航到上一个 View 。

我的代码非常简单:

dispatch_queue_t queue = dispatch_queue_create("com.x.y.z", NULL);
dispatch_async(queue, ^{
    TestObject* test = [self getTestObject];
    dispatch_async(dispatch_get_main_queue(), ^{
        test.resultset.count > 0 ? 
             [self performSegueWithIdentifier:@"xy" sender:self] :
             [UIUtils showSimpleAlert:NSLocalizedString(@"NoDataForInterval",nil) 
                             delegate:self];
    });
});

异常信息:由于未捕获的异常而终止应用NSGenericException,原因:

Could not find a navigation controller for segue 'xy'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.

所以,问题是,当我的用户返回到上一个 View 时,GCD 中的任务会继续,完成后,它会使我的应用程序崩溃,因为无法执行我的转场。

所以,我的问题是:导航到另一个 View 时如何取消 GCD 中的 asny 任务?或者只是在完成时以某种方式测试当前 View ,例如

if(!self.navigationController)
    return;

或者……?

谢谢大家!

最佳答案

if(!self.navigationController)
    return;

那么你尝试过吗?返回主线程后,查看界面的状态是完全安全且合理的。

另一方面,如果您确实希望轻松取消中间的冗长任务,请使用 NSOperation 而不是 GCD block 。这为您提供了线程安全的取消 API。

关于ios - 返回时取消 GCD 异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16400248/

相关文章:

ios - Xcode将新文件添加到SVN中的现有项目

javascript - 如何从 Angular 工厂发送带有循环的程序请求(一个接一个)?

javascript - 如何使 for 循环等待异步函数

flutter - 如何在迭代器中使用ListView

iphone - 正确分配/取消分配 UINavigationControllerDelagate

ios - 根据来源不同,Unwind Segue 也不同

ios - TouchID "On"与 "On but suspended"

ios - 如何使用 ObjectMapper 映射此 JSON?

ios - 更多选项卡 View Controller 选择器及其各自的 View Controller 顶部的白色栏

ios - 在 BluetoothManager Delegate 类中访问 ViewController 按钮