3

我在我的iOS應用程序的視圖控制器中有一個相對較長的運行任務(5-10秒)。它由GCD在後臺運行異步。用戶可以在此任務中進行UI操作,因此他還可以按下後退按鈕導航到前一個視圖。在導航時取消GCD異步任務

我的代碼是非常簡單的:

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,原因是:

找不到賽格瑞 'XY' 導航控制器。只有當源控制器由UINavigationController的實例管理時才能使用推塞網。

所以,問題是,當我的用戶回到上一個視圖時,GCD中的任務仍在繼續,當完成時,它會崩潰我的應用程序,因爲無法執行我的搜索。

所以,我的問題是:如何在GCD導航到另一個視圖時取消我的asny任務?完成時,像

if(!self.navigationController) 
    return; 

或者或者只是簡單地測試了不知何故當前視圖...?

謝謝大家!

+0

[暫停GCD查詢問題]的可能的重複(http://stackoverflow.com/questions/6737044/suspending-gcd-query-problem) – matt 2013-05-06 14:30:45

回答

2
if(!self.navigationController) 
    return; 

所以你嘗試了嗎?一旦你回到主線程,看看接口狀態是完全安全和合理的。

另一方面,如果您確實想要輕鬆取消中間冗長的任務,請使用NSOperation而不是GCD塊。這給你一個線程安全的取消API。

+0

是的,我試過了,但我認爲這是一個醜陋的解決方案,在那裏是一個更好的。 – Tom 2013-05-06 16:25:43

+0

我不明白爲什麼它很醜,但正如我已經說過,如果你真的想在中間取消,NSOperation是要走的路。你只需要在你的操作過程中定期檢查'isCancelled',如果是的話就保釋。即使操作(和「isCancelled」)發生在後臺,它也是線程安全的,可以取消主線程。 – matt 2013-05-06 16:31:58