2016-02-04 55 views
0

我的問題很簡單,但經過許多研究和測試後,在繼續流程之前,我沒有成功等待函數結束。如何等待函數調用在Swift結束

例子:

print("Before stuff") 
do_stuff { 
    print("After stuff") 
} 


func do_stuff(onCompleted:() ->()) { 
    let postEndpoint: String = "http://localhost:8080/users/1234567890987654" 
    guard let url = NSURL(string: postEndpoint) else { 
     print("Error: cannot create URL") 
     return 
    } 
    let urlRequest = NSURLRequest(URL: url) 
    let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
    let session = NSURLSession(configuration: config) 
    let task = session.dataTaskWithRequest(urlRequest, completionHandler: { 
    (data, response, error) in 
    guard let responseData = data else { 
     print("Error: did not receive data") 
     return 
    } 
    guard error == nil else { 
     print("error calling GET on /users/1234567890987654") 
     print(error) 
     return 
    } 
    // parse the result as JSON 
    let user: NSDictionary 
    do { 
     user = try NSJSONSerialization.JSONObjectWithData(responseData, 
      options: []) as! NSDictionary 
    } catch { 
     print("error trying to convert data to JSON") 
     // Means that user does not exist 
     return 
    } 
    print("The user is: " + user.description) 
    }) 
    task.resume() 
    onCompleted() 
} 

如何等待do_stuff第二打印()之前結束了嗎?

感謝您的幫助,我想我錯過了什麼。

托馬斯

+1

隨着代碼的寫入,第二個'print'調用肯定會在'do_stuff'完成執行後執行。函數的實現方式有什麼特別之處嗎? – Cristik

+0

不要等待!回電或通知 – vadian

+0

@Cristik:比方說,在do_stuff中,長操作像REST API調用一樣執行。 – Thomi

回答

1

有一些基本的東西,你的天堂」不瞭解。它實際上並不是正在執行的功能。這是函數內部定義的閉包。你需要等待的是在請求完成時調用閉包。事實上,你不應該等待,而是在函數外部分配另一個閉包,以從函數內部的閉包調用。

print("Before stuff") 
do_stuff { 
    // Now the "function" has completed. 
    print("After stuff") 
} 

func do_stuff(onCompleted:() ->()) { 
    let task = session.dataTaskWithRequest(urlRequest) { data, response, error in 
     ... 
     onCompleted() 
    } 
} 
+0

謝謝你的回答。我只是用你的建議編輯了我的代碼,但不幸的是我仍然在我的「print(」用戶是...「)之前打印出」After stuff「」:(「 – Thomi

+0

」)你是如何編輯代碼的?如果打印行是在onCompleted調用之前,不可能在「用戶是......」之前打印「After stuff」。onCompleted必須是封閉中的最後一行。 – Tapani

+0

是的,我已經知道了,我的onCompleted()被放錯了位置,我只是糾正了它那很好,謝謝 – Thomi

0

你總是可以使用一個完成處理程序do_stuff()功能:

func do_stuff(completion: (() -> Void)?) ->() { 
... 
    if completion != nil { 
     return completion!() // Return completion where you want you "after stuff" declarations to run. 
    } 
} 

,並調用功能,例如:

do_stuff({ 
    print("After stuff") 
})