2015-04-17 54 views
-2

我對GCD很新,我不確定我是否做錯了什麼。我的代碼是這樣的:dispatch_async仍然阻止我的用戶界面

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       if([manager updateRecord:foodRecord]) // this function will connect to a web server, and might take a few seconds. If I remove it, the UI will be smooth as butter 
       { 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         [cell expandAnimation]; // this function calls a series of UIView animateWithDuration to basically scale the cell and then call a reloadData when it's done 
        }); 
       } 
      }); 

任何想法爲什麼它仍然會導致同步行爲?我嘗試使用GCD之前和之後似乎沒有區別。

+1

這種「同步行爲」究竟是什麼?你是說在這個dispatch_async後面沒有一行代碼嗎?無論如何,這個問題並不在上面的代碼中。也許在'updateRecord'方法中。如WWDC 2012視頻[在iOS上構建併發用戶界面](https://developer.apple.com/videos/wwdc/2012/?id=211)中所示,您可以隨時使用「記錄等待線程」選項。 – Rob

+0

管理器的-updateRecord方法是線程安全的嗎?如果不是這樣,你是否在同一個線程上實例化和訪問經理資源? – bteapot

+0

請在'updateRecord'方法中分享你的代碼..似乎有一些問題。 – itsji10dra

回答

0

我不確定你的「同步行爲」的想法是什麼,但dispatch_async模式的主要好處是,動畫(如tableView滾動和其他轉換)可以繼續而不會出現口吃和結束用戶應用程序感覺響應。在5秒鐘的Web服務器調用完成之前,它將無法顯示更多數據或根據可用數據更新UI。

也許您需要在第一次dispatch_async調用之前使用「加載數據」類型消息更新單元格或顯示活動指示符,以通知用戶。

然後在開始dispatch_async之後,用戶在等待< 5秒鐘時仍然應該對用戶感覺響應(例如可滾動的tableView等)。然後在dispatch_async回到主隊列中,這個「加載」UI狀態可以被刪除(在這裏插入設計器魔術),然後打電話給你的[cell expandAnimation];完成它。

如果你仍然看到用戶界面上出現口吃,那麼[manager updateRecord:foodRecord]可能會對返回的網頁數據進行非常繁重的處理,這可以用TimeProfiler工具進行進一步調查,但我認爲這是一個單獨的問題。

+0

謝謝,您的回答爲我提供了一些非常有用的信息。 – CyberMew

0

問題不在於上面顯示的gcd代碼或用戶代碼。

問題是另一個偵聽指令的套接字,並且在調用updateRecord方法時,套接字也正在接收一些正在主線程上執行的指令。這不是即時的,因此gcd代碼由於某種原因而不起作用的錯覺。這也增加了解決問題的難度,因爲上面的代碼與問題沒有直接關係。

因此,如果您正在閱讀本文,請更廣泛地考慮您的應用程序如何工作(內部),並檢查應用程序中還有哪些應用程序正在運行!