iOS UILabel 视图更新有延迟,即使控制台立即显示输出

iOS UILabel view updating has a delay even though console shows output immediately

我正在尝试更新我视图中的几个 UILabel,但我遇到了更新延迟的问题。我正在创建一个 NSURLSession,我不知道这是否是导致问题的原因,但我能够毫不延迟地更新这段代码之外的其他 UILabel。

执行此代码时,我立即在输出控制台中看到了前两个 println 及其值,以及带有字符串 "done" 的第三个 println。但是在模拟器中,activityIndi​​cator 运行,然后大约 15 秒后 UILabels 更新并且 activityIndi​​cator 停止。这不是 activityIndi​​cator 的问题,因为即使我取出该代码,UILabels 更新仍然存在延迟。而且我知道在更新 UILabel 之前并没有真正等待数据返回,因为值显示在输出控制台中。

关于视图 updating/display 中为什么会有延迟的任何想法?还有为什么控制台输出似乎跳过更新和打印 "done" 字符串,而实际上它上面的代码行尚未完成?

    @IBOutlet var attribute1: UILabel!
    @IBOutlet var attribute2: UILabel!
    ...
    var url = NSURL(string: "http://www.example.com")
    if url != nil {
        let task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: {
            (data, response, error) -> Void in
            var urlError = false
            if error == nil {
                var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as String!

                // we then parse out the relevant bits of data
                var urlContentArray = urlContent.componentsSeparatedByString("<header class=\"blah\")
                if urlContentArray.count > 0 {
                    var attributesArray = urlContentArray[1].componentsSeparatedByString("<span class=\"something\">")
                    var att1Array = attributesArray[1].componentsSeparatedByString("</span>")
                    var att2Array = attributesArray[2].componentsSeparatedByString("</span>")

                    println(att1Array[0])
                    println(att2Array[0])
                    self.attribute1.text = att1Array[0]
                    self.attribute2.text = att2Array[0]
                    println("done")
                    self.activityIndicator.stopAnimating()
                } else {
                    urlError = true
                }
            } else {
                urlError = true
            }
            if urlError == true {
                self.showURLError()
            }
        })
        task.resume()
        self.activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, screenSize.width, 930))
        self.activityIndicator.hidesWhenStopped = true
        self.activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.White
        self.view.addSubview(self.activityIndicator)
        self.activityIndicator.startAnimating()
    } else {
        showURLError()
    }

NSURLSession 在后台线程上执行,但您应该始终在主线程上更新 UI 元素。

dispatch_async(dispatch_get_main_queue()) {
    self.attribute1.text = att1Array[0]
    self.attribute2.text = att2Array[0]
    self.activityIndicator.stopAnimating()            
}