2

我在我的應用程序中使用Grand Central Dispatch以便在後臺運行方法。該方法基於用戶的輸入來計算一些數學數據,並且需要一些時間來這樣做。請記住它不使用互聯網。取消派遣隊列

無論何時加載主視圖,我都運行這個背景「計算」方法(這是一個調度隊列)。問題是,如果用戶在後臺運行方法時切換應用程序中的視圖,則應用程序會崩潰。

有什麼辦法可以「取消」隊列/停止代碼塊在用戶切換視圖時運行嗎?另一種想法是通過查看iPhone Weather.app。當天氣加載時,它會在後臺下載數據,並在下載時按下角落中的小信息按鈕不會使應用程序崩潰。

謝謝!

queue = dispatch_queue_create("com.mycompany.myqueue", 0); 

dispatch_async(queue, ^{ 
    //make some complicated calculations 
}); 

回答

2

一旦塊開始執行,掛起隊列本身不會幫助你。但是您可以使用__block限定符定義一個名爲'cancel'的BOOL,然後在計算的適當階段(每次迭代或其他段),可以在繼續之前檢查'取消'是否爲NO。

1

其他人已經提出了設置共享取消標誌的簡單方法(這是因爲GCD不支持隱式取消應該如何進行取消),但是當用戶切換視圖時應用程序崩潰也意味着存在在特定綁定到UI狀態的塊內完成工作。當用戶離開時,背景塊被這個致命混淆的事實表明你確實需要重構一些代碼。您應該已經在派發主隊列上的所有AppKit或UIKit調用,因爲它們不會從其他任何人調用,所以必須有一個對象引用在用戶切換視圖時發生更改,並且您只需要爲在手術被立即取消的情況下之後您的檢查,並且您仍然在將用戶交互競爭到最終粘性的末端。 GCD將多線程代碼的負擔減輕了很多,但它不是解決共享對象引用等併發問題的靈丹妙藥 - 這些仍然存在並且是很難解決的問題,GCD只是使它更容易修復它們(比如允許爲代碼中的每個共享/爭用對象創建相應的串行隊列,並重構setter/getter方法以將該隊列用作併發障礙)。