iOS请求后需要很长时间才能更新视图?

时间:2014-08-24 02:49:49

标签: ios http swift

我是学习iOS和Swift的新手,所以这里可能有一些非常基本的东西我不明白。我正在使用agent库在Swift中发送HTTP请求。现在,我正忙着创建请求并解析JSON响应。

我有一个非常简单的用户界面,其中包含一个按钮和UILabel,我想用一些JSON的结果更新。

这是我的代码:

func updateWithJson() -> Void {
    let req = Agent.get("http://xkcd.com/info.0.json")
    req.end({ (response: NSHTTPURLResponse!, data: Agent.Data!, error: NSError!) -> Void in
        let json = data! as Dictionary<NSString, NSString>
        // this takes almost 30 seconds to propagate to the UI...
        self.updateMe.text = json["safe_title"]!
    })
}

我不理解的部分是self.updateMe.text = json["safe_title"]!语句,它只是更新名为UILabel的{​​{1}}上的某些文字。这需要几乎整整30秒才能在UI中反映出来。

我知道HTTP请求本身非常快 - 如果我卷曲该URL,它会立即恢复。似乎updateMe对象正在建立连接并且响应速度非常快。

我错过了一些非常基本的东西吗?我应该以不同的方式更新UI吗?所有指针都很受欢迎!

更新 通过另一个SO帖子,我理解Agent内部的块是后台线程,我需要在主线程上进行UI更新。我更新了我的功能,看起来像这样,我得到了理想的结果。但是,现在我想知道这样做是否有些不正确的事情?

req.end

1 个答案:

答案 0 :(得分:5)

正在发生的事情是您的HTTP请求正在后台线程上运行。当它调用你提供的回调时,你仍然在那个后台线程上。在iOS 所有UI工作必须在主线程上完成。最简单的方法是使用GCD的dispatch_async,如下所示:

dispatch_async(dispatch_get_main_queue()) {
    [weak self] in
    self?.updateMe.text = json["safe_title"]!
    return
}

所以你的整个功能看起来像是:

func updateWithJson() -> Void {
    let req = Agent.get("http://xkcd.com/info.0.json")
    req.end({ (response: NSHTTPURLResponse!, data: Agent.Data!, error: NSError!) -> Void in
        let json = data! as Dictionary<NSString, NSString>
        dispatch_async(dispatch_get_main_queue()) {
            [weak self] in
            self?.updateMe.text = json["safe_title"]!
            return
        }
    })
}

关于[weak self] in的位是这样的,因此您不会创建strong reference cycle。最后的return是因为你有一个只有一个表达式的闭包。在这种情况下,Swift将尝试implicitly return a value based on that statement,在这种情况下,这不是你想要的。