2014-11-02 72 views
0

在我的iOS應用程序中,我需要通過使用PFObject查詢來檢索一些值。當這些都加載時,應用程序應該繼續做更多的東西。Parse.com查詢和應用程序設計問題:在主線程上執行長時間運行的操作

func processTransaction(){ 

    .. some code to prepare my 2 queries 

    var balance1 = balance1Query.getFirstObject() as PFObject; 
    var balance2 = balance2Query.getFirstObject() as PFObject; 

    .. after these are loaded i have to update them, and 'release' the screen to the user. 
} 

現在,使用這種方法.getFirstObject()的時候,我得到了我的的Xcode調試窗口說一個警告:

長期運行的操作被主線程上執行。

當然,我做了一些研究,每一個答案,我閱讀有關使用 getObjectInBackgroundWithId,然後移到這些查詢的執行的背景會談(我猜它這樣做使他們在一個新的線程。)

但我的問題是,在代碼繼續使用這些對象之前,我應該如何構造我的代碼/設計,以確保兩個對象都已加載?

我嘗試了一些東西,創造像下面一些代碼,但我感覺這是不正確的方法。當我不得不加載並確保加載4或5個對象時,無法想象這會變成什麼樣子。

balanceQuery1.getFirstObjectInBackgroundWithBlock{ 
    (balance1: PFObject!, error1: NSError!) -> Void in 
    if error1 == nil { 
     balanceQuery2.getFirstObjectInBackgroundWithBlock{ 
      (balance2: PFObject!, error2: NSError!) -> Void in 
      if error2 == nil { 
       ... processing here.. 
      } 
    } 
} 
+3

不,這是正確的做法。只要記住派發任何代碼,將您的UI更新回主隊列。對於balanceQuery2,您可以使用getFirstObject,因爲您已經離開主隊列 – Paulw11 2014-11-02 20:51:58

+0

嗯..好的。感謝您的回覆。但是,我還在想,除了嵌套,嵌套和嵌套之外,沒有別的辦法嗎?在.NET中我有等待,我可以鏈任務(http://msdn.microsoft.com/en-us/library/dd537610(v=vs.110).aspx)。在iOS/Swift中沒有類似的東西嗎? – Tys 2014-11-02 22:20:48

回答

1

我的建議,你的做法是正確的基礎上的要求執行兩個查詢 - 在這種情況下,你可以派遣第一查詢到後臺,然後在完成塊執行後續查詢。

如果你正在尋找一個更一般的異步調度模型,那麼我會建議使用調度組的活動同步。要有效地使用這種技術,最好在數組或類似的數據結構中進行查詢。(道歉,我沒有把它轉換成Swift,但它基本上是一樣的)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_group_t group = dispatch_group_create(); 

// Add a task to the group 

for (int i=0;i<self.queries.count;i++) { 


    dispatch_group_async(group, queue, ^{ 
     self.queries[i].getFirstObject ... 
    }); 
} 

// When you cannot make any more forward progress, 
// wait on the group to block the current thread. 
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

// Release the group when it is no longer needed. 
dispatch_release(group); 
+0

謝謝,我可以使用這個! – Tys 2014-11-03 08:10:26

0

如果你想避免嵌套,有第二種方法是有用的,特別是如果你有很多的查詢運行。三個步驟:

  1. 設置一個int completedQueries變量爲0,將被遞增,當查詢完成
  2. 設置一個int totalQueries變量表示的查詢的總數完成
  3. 對於每個查詢的完成塊,增量completedQueries和運行一個函數,以檢查是否完成次數是等於總:

    balanceQuery1.getFirstObjectInBackgroundWithBlock{ 
        (balance1: PFObject!, error1: NSError!) -> Void in 
        if error1 == nil { 
         completedQueries++ 
         checkQueriesCompleted() 
        } 
    } 
    //balanceQuery2, 3 and so on below... 
    

最後,有一個checkCompletedQueries功能等待你的總完成相等:

func checkQueriesCompleted() { 
    if (completedQueries == totalQueries) { 
     //... processing here .... 
    } 
} 

這種結構是特別強大,如果你有3+的功能,或者您有來電任意數量。當我想要解決Parse上的1000個項目返回限制時(使用.skip參數獲取多個對象,根據需要創建多個調用,在處理之前等待所有返回),我會使用它很多 - 理念。

+0

而且,我必須說,這看起來也是一個有趣的想法! – Tys 2014-11-03 15:30:43

相關問題