我在ViewDidLoad()下调用了以下方法。我知道session.dataTaskWithRequest自动在后台线程中运行。因此,ViewDidLoad()中此方法之后的代码不会等待此过程完成并开始执行。
有没有什么办法可以确保在执行其他方法之前完成后台线程?
func getCoordinatesFromServer() {
let request = NSMutableURLRequest(URL: NSURL(string: constants.urlName.loadData)!)
request.HTTPMethod = "POST"
request.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
request.setValue("keep-Alive", forHTTPHeaderField: "Connection")
request.HTTPBody = (constants.requestTag.getCoordinates).data
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error ) in
if let response = response {
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
if (httpResponse.statusCode == 200) {
dispatch_async(dispatch_get_main_queue(), {
let decodedData = NSData(base64EncodedData: data!, options: NSDataBase64DecodingOptions([]))
let jsonText = NSString(data: decodedData!, encoding: NSASCIIStringEncoding) as! String
do {
let json = try NSJSONSerialization.JSONObjectWithData(jsonText.data, options: NSJSONReadingOptions.init(rawValue: 0))
self.parseJsonData(json["Datalist"] as! NSArray)
} catch {
print("Error:\n \(error)")
}
})
}
}
})
task.resume()
}
此致
答案 0 :(得分:1)
如果我理解你的问题,你就可以通过这种方式解决这个问题 例如:
class func ConnectedToNetwork(completionHandler: ((Status: Bool) -> Void))
{
let url = NSURL(string: "http://google.com")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.timeoutInterval = 0.2
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data,response, error) in
let httpResponse = response as! NSHTTPURLResponse
if httpResponse.statusCode == 200
{ completionHandler(Status: true)
return
}
}
task.resume()
}
然后,你可以使用这个
Checks.ConnectedToNetwork({ Status in dispatch_async(dispatch_get_main_queue())
{
if Status == true
{
//do what you want
}
});
答案 1 :(得分:0)
dataTaskWithRequest
是同步调用,它有completionHandler
阻止。因此,您在内部编写的所有代码都将在数据任务完成后执行:
let request = NSURLRequest(URL: NSURL(string: "http://google.com")!)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {(data, response ,error ) in
print("3") // executed after data task is finished
print("4") // executed after data task is finished
})
task.resume()
print("1")
print("2")
答案 2 :(得分:-1)
import Foundation
// some aync function with completition handler, i MUST USE AS IT IS
func f(completitionHandler: ()->()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { () -> Void in
print("running concurrently")
sleep(1)
print("finished")
completitionHandler()
}
}
// some function running on main queue
func foo() {
// create dispatch group
let group = dispatch_group_create()
let myCompletitionHandler: ()->() = {
dispatch_group_leave(group)
}
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
dispatch_group_async(group, queue) { () -> Void in
dispatch_group_enter(group)
f(myCompletitionHandler)
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
}
foo()
print("foo finished")
这不是最好的,更好的解决方案是运行f()的同步版本而不是这个'变通方法': - )