iphone - iOS UILabel View 更新有延迟,即使控制台立即显示输出

标签 iphone swift ios8 uilabel synchronous

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

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

关于为什么 View 中的更新/显示会延迟的任何想法?还有为什么控制台输出似乎跳过更新并打印“完成”字符串,而实际上它上面的代码行尚未完成?

    @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()            
}

关于iphone - iOS UILabel View 更新有延迟,即使控制台立即显示输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28668075/

相关文章:

javascript - 如何从 block 函数中获取数据?

iphone - 移动样式表不适用于 iPhone

ios - 未调用 alertViewShouldEnableFirstOtherButton 委托(delegate)方法

iphone - 用于 iOS 开发的 LLVM 与 GCC

swift - 应用程序未运行时跟踪地理位置 (Swift)

ios - 使用 UISplitViewController 的 Tableview 作为过滤器

ios - 阻止 UITableView 在 iOS 8 中自动滚动

ios - 同时显示 UIAlertView 和键盘

ios - Swift - 实例化新 View Controller 时如何保留对旧 View Controller 的引用?

ios - UiWebView 委托(delegate)方法未被调用