iOS UILabel 视图更新有延迟,即使控制台立即显示输出
iOS UILabel view updating has a delay even though console shows output immediately
我正在尝试更新我视图中的几个 UILabel,但我遇到了更新延迟的问题。我正在创建一个 NSURLSession,我不知道这是否是导致问题的原因,但我能够毫不延迟地更新这段代码之外的其他 UILabel。
执行此代码时,我立即在输出控制台中看到了前两个 println 及其值,以及带有字符串 "done" 的第三个 println。但是在模拟器中,activityIndicator 运行,然后大约 15 秒后 UILabels 更新并且 activityIndicator 停止。这不是 activityIndicator 的问题,因为即使我取出该代码,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()
}
我正在尝试更新我视图中的几个 UILabel,但我遇到了更新延迟的问题。我正在创建一个 NSURLSession,我不知道这是否是导致问题的原因,但我能够毫不延迟地更新这段代码之外的其他 UILabel。
执行此代码时,我立即在输出控制台中看到了前两个 println 及其值,以及带有字符串 "done" 的第三个 println。但是在模拟器中,activityIndicator 运行,然后大约 15 秒后 UILabels 更新并且 activityIndicator 停止。这不是 activityIndicator 的问题,因为即使我取出该代码,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()
}