2015-06-10 66 views
1

我想從我的RestAPI獲取數據,特別是我得到一個整數數組(這是其他用戶的ID),我想循環這個數組並下載數據來自所有其他客戶。代碼的簡化版本如下所示。返回for循環中的異步請求

func asyncFunc(completion: (something:[Int])->Void){ 
    //Get a json Array asynchonous from my RestAPI 
    let jsonArray = [1,2,3,4,5] 

    var resultingArray:[Int] = [] 

    for myThing in jsonArray{ 
    anotherAsyncFunc(myThing, completion: { (somethingElse) -> Void in 
     resultingArray.append(somethingElse) 
    }) 
    } 
} 

func anotherAsyncFunc(data:Int, completion: (somethingElse:Int)->Void){ 
    //Get some more jsonData from RestApi/data 
    let myLoadedData:Int = data*13356 
    completion(somethingElse: myLoadedData) 
} 

我怎麼會讓我asyncFunc它已經從第二(內)異步請求得到的所有物品返回數組。

我已經嘗試獲得第一個從其他Api請求的數組的計數,並通過使用while循環僅「阻塞」UI線程也看到「新」數組已收集所有數據(計數等於第一個請求數組的數量)。這有兩個主要的缺點,主要是它阻塞了UI線程,更進一步說,它會失敗,並在應用程序崩潰時,如果數據連接在我從其他用戶(內部異步請求)獲取數據時斷開,導致循環永遠不會完成。

我的問題是我將如何使用完成處理程序返回它應該返回的所有數據,而不會阻塞主線程和/或不必擔心嚴重時間的數據連接丟失。

回答

2

您可以使用調度組通知。因此,創建一個調度組,爲數組中的每個項目輸入組,退出anotherAsyncFunc異步過程的完成處理程序,然後創建一個通知,當所有dispatch_group_enter調用已被偏移量爲1時,將觸發最終的completion關閉。相應dispatch_group_leave電話:

func asyncFunc(completion: (something:[Int])->Void){ 
    //Get a json Array asynchonous from my RestAPI 
    let jsonArray = [1,2,3,4,5] 

    var resultingArray:[Int] = [] 

    let group = dispatch_group_create() 

    for myThing in jsonArray { 
     dispatch_group_enter(group) 
     anotherAsyncFunc(myThing) { somethingElse in 
      resultingArray.append(somethingElse) 
      dispatch_group_leave(group) 
     } 
    } 

    dispatch_group_notify(group, dispatch_get_main_queue()) { 
     completion(something: resultingArray) 
    } 
} 

注意,你將要確保你的anotherAsyncFunc正在執行的同步更新到resultingArray。最簡單的方法是確保它將更新發送回主隊列(如果您的REST API沒有這樣做)。

func anotherAsyncFunc(data:Int, completion: (somethingElse:Int)->Void){ 
    //Get some more jsonData from RestApi/data asynchronously 
    let myLoadedData:Int = data*13356 
    dispatch_async(dispatch_get_main_queue()) { 
     completion(somethingElse: myLoadedData) 
    } 
} 

這僅僅是一個例子。您可以使用任何您想要的同步機制,但請確保相應地同步resultingArray上的更新。

+0

謝謝,永遠不知道這個功能。像魅力一樣工作!這將如何處理在下載時丟失數據連接? – milo526

+0

在Swift 1.2中,你通常會在anotherAsyncFunc的'completion'塊參數中添加一個可選的錯誤參數,並使'somethingElse'成爲一個可選參數,並且確保調用'completion'塊是否成功(設置錯誤或酌情引用「somethingElse」)。 – Rob