2015-04-26 32 views
0

我創建了一個函數,該函數應該返回一個填充了數據的字典(使用json,基於Ray Wenderlich tut)。該代碼處於關閉狀態。問題是一個空字典首先被返回,並且只有在它被填充之後。不知道這是否與延遲獲取遠程數據有關,但顯然我需要在返回字典之前先填充字典。這是代碼。來自包含閉包的swift函數的空返回值

func getStatusFromRemoteSource() -> [StatusModel] { 

    var statusUpdates = [StatusModel]() 
    println("statusUpdates after initialization: \(statusUpdates)") // 1 

    DataManager.getStatusDataWithSuccess { (statusData) -> Void in 
     let json = JSON(data: statusData) 

     if let jsonArray = json.array { 

      for jsonItem in jsonArray { 
       var statusVersion: String? = jsonItem["version"].string 
       var statusDescription: String? = jsonItem["message"].string 
       var statusCode: Int? = jsonItem["code"].string!.toInt() 

       var update = StatusModel(version: statusVersion, message: statusDescription, code: statusCode) 
       statusUpdates.append(update) 
       println("statusUpdates after appending update: \(statusUpdates)") // 3 (after other function call) 
      } 

      let item = 0 
      println("Version \(statusUpdates[item].version) has status \(statusUpdates[item].message)") 
      // println("Status code: \(statusUpdates[item].code)") 
     } 
    } 

    println("Status updates before return: \(statusUpdates)") // 2 
    return statusUpdates 
} 

所以//1首先打印,然後//2(仍然爲空),然後其他的功能(即調用此一個)被調用。只有//3與正在檢索的內容一起打印(正確)。

如何在返回之前填入statusUpdates字典?

+0

你應該在這種情況下考慮使用閉包! –

+0

異步完成的函數不能返回值,因爲如您所述,數據尚未被檢索。你可以給函數提供一個閉包,或者從這個函數的成功閉包中調用另一個函數 – Paulw11

回答

1

您應該在方法中使用閉包來將statusUpdates作爲其異步方法返回。 空的StatusUpdates將在你的代碼立即返回,但使用時關閉,你可以等到DataManager.getStatusDataWithSuccess完成:

typealias RemoteStatusHandler = (status:[StatusModel]) -> Void 


func getStatusFromRemoteSource(handler:RemoteStatusHandler){ 

var statusUpdates = [StatusModel]() 
println("statusUpdates after initialization: \(statusUpdates)") // 1 

DataManager.getStatusDataWithSuccess { (statusData) -> Void in 
    let json = JSON(data: statusData) 

    if let jsonArray = json.array { 

     for jsonItem in jsonArray { 
      var statusVersion: String? = jsonItem["version"].string 
      var statusDescription: String? = jsonItem["message"].string 
      var statusCode: Int? = jsonItem["code"].string!.toInt() 

      var update = StatusModel(version: statusVersion, message: statusDescription, code: statusCode) 
      statusUpdates.append(update) 
      println("statusUpdates after appending update: \(statusUpdates)") // 3 (after other function call) 
     } 

     let item = 0 
     println("Version \(statusUpdates[item].version) has status \(statusUpdates[item].message)") 
     // println("Status code: \(statusUpdates[item].code)") 
    } 

    handler(status: statusUpdates) 
} 


} 

然後你的函數可以這樣調用:

getStatusFromRemoteSource { (status) -> Void in 
    //use status here, this function is void. 
} 
+0

感謝代碼,這有助於!有一件事:我從另一個函數中調用'getStatusFromRemoteSource',並想將'[StatusModel]'字典綁定到一個變量。如果(在另一個函數中)我讓'statusUpdates = getStatusFromRemoteSource {(status) - > void in ...}'不起作用。猜測返回類型不應該是無效的我在typalias定義和函數調用中都將其更改爲'[StatusModel]',但它仍然不會採用它。有什麼建議麼? – Pieter

+0

不只是使用: getStatusFromRemoteSource {(狀態) - > //在這裏使用狀態 } 因爲getStatusFromRemoteSource將是void,不會返回任何東西。你會傳給它一段代碼。 –

+0

感謝一百萬,它的工作原理!顯然,與以前使用的直接方法相比,加載狀態需要更多時間,但是這可以完成工作! – Pieter