Swift异步HTTP请求是否会创建另一个线程?

时间:2017-03-19 15:39:44

标签: ios swift multithreading asynchronous swift3

我有两个问题。

第一个是“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()

1 个答案:

答案 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()

的调用中