我有两个问题。
第一个是“swift异步http请求是否会创建另一个线程”?
第二个问题是我有一个表视图,在我的http请求之后,我需要根据从服务器检索到的数据刷新我的tableview。但是,如果我在dispatch_async闭包之外执行self.tableview?.reloadData,它将无法工作。 (经过很长时间后会刷新。)
所以我的问题是为什么会发生这种情况?为什么我不能在那个线程中刷新tableview而不返回主线程?
我一直在寻找swift http请求及其机制的解释。如果有人想详细解释,我真的很感激!
我已附上我的工作代码
let request = NSMutableURLRequest(URL: NSURL(string: "http://xxx/getAllposts.php")!)
request.HTTPMethod = "POST"
let postString = "user=ios"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = try! NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
if responseString!["success"] as! Int == 0{
return
}
let array:NSArray = responseString!["all"] as! NSArray
dispatch_async(dispatch_get_main_queue()) { [unowned self] in
self.values = array
self.tableView?.reloadData();
}
}
task.resume()
答案 0 :(得分:0)
您的问题不是关于“Swift异步HTTP请求”,而是关于NSURLSession
(Swift 3中的OR URLSession
)。您可以从Objective-C调用来自Swift的NSURLSEssion,以及可能来自C ++或C.语言并不重要。
NSURLSession
支持异步网络请求。这意味着当您的程序继续运行时,“繁重”将在后台完成。异步API几乎总是编写为在后台线程上完成工作,但还有其他方法可以做同样的事情。 (例如,在较旧的硬件上,异步通信可能使用中断进行处理。)
在幕后,NSURLSession
使用共享线程池来完成工作。所以它确实在单独的线程上进行网络事务,但它没有为此创建一个唯一的线程(在时间和系统资源方面创建线程非常昂贵。维护共享线程池和根据需要使用它们。)
任务完成后,NSURLSession会告诉调用者。它可以通过完成处理程序或委托来完成。完成方法和委托方法都在串行操作队列上执行。 (在两种情况下都称为委托队列。)默认情况下,NSURLSession会为您创建该操作队列,并在后台线程上运行。如果您使用默认的NSURLSession
我认为您不能更改委托队列。如果您创建自己的NSURLSession
,可以将其设置为使用在主线程上运行的调度队列,但我不建议使用它。在后台线程上进行数据处理是一件好事。
这意味着通常发送给您的有关您的任务的消息将在后台线程上发送。
大多数UIKit调用必须在主线程上运行。如果不这样做,结果是不确定的(从UI更新中的长延迟到崩溃和其他奇怪的行为。)
必须在主线程上执行tableView.reloadData()
之类的调用。这就是为什么你必须把它包裹在DispatchQueue.main.async()