gpt4 book ai didi

ios - 在 DispatchQueue.main.async 中完成某些处理后,更新 UI 控件会出现滞后

转载 作者:行者123 更新时间:2023-11-28 15:08:14 25 4
gpt4 key购买 nike

尝试从 DispatchQueue.main.async 闭包更新 UI 控件,该闭包执行一些处理并需要几百毫秒或更长时间,UI 标签的更新有几秒到几秒的延迟。如果没有延迟或延迟时间很短,则 UI 中的标签更新会在代码运行时发生并且似乎是即时的。

我有这个小例子来说明我添加了一个“等待毫秒”函数来模拟处理时间并显示出现的 UI 更新滞后的问题。

在示例中,waitForMilliSecs 设置为 300 或更少,标签会即时更新。任何大于 300 的数字都会延迟更新标签几秒到几秒。那里的日志消息表明代码已经运行,理想情况下,UI 应该在打印出来时进行更新。

class ViewController: UIViewController {

@IBOutlet weak var label1: UILabel!

@IBOutlet weak var label2: UILabel!

override func viewDidLoad() {
super.viewDidLoad()

DispatchQueue.main.async {
os_log("before")
self.label1.text = "updated label 1 1111"
self.label2.text = "updated label 2 2222"
self.waitForMilliSecs(MilliSecs: 300)
os_log("after")
}

}

func waitForMilliSecs(MilliSecs millisecs: Int) -> Void {
var date = NSDate()
let firstTime = Int64(date.timeIntervalSince1970 * 1000)
var currentTime = firstTime
while currentTime - firstTime < millisecs {
date = NSDate()
currentTime = Int64(date.timeIntervalSince1970 * 1000)
}
}

真正的用例是我正在抓取一个 HTML 页面以获取数据,然后使用该页面的一些内容更新 UI。完成处理程序是从后台线程上的 URLSession.shared.dataTask 调用的,因此 DispatchQueue.main.async 闭包用于更新主线程上的 UI。

是否有更好的方法来更新 UI?有没有办法强制更新主线程上的事件?

最佳答案

没有比在主线程上更新 UI 更好的方法了。

但是你所做的并不完全正确。您也在主线程上进行处理(函数 waitForMilliSecs)。这也许不是您想要的。您需要在后台线程上进行处理,当处理完成后,在主线程上更新 UI。

override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
print("before")
//this function is doing some real work and produces some results.
self.waitForMilliSecs(MilliSecs: 3000)
print("after")

DispatchQueue.main.async {
self.label1.text = "updated label 1 1111"
self.label2.text = "updated label 2 2222"
}
}
}

github repo 展示了整个例子: https://github.com/jurajantas/TestOfBackgroundProcessing.git

关于ios - 在 DispatchQueue.main.async 中完成某些处理后,更新 UI 控件会出现滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48117980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com