gpt4 book ai didi

ios - 在我们完成 DispatchWorkItem 并尝试使用 DispatchQueue.main.async 更新 UI 后,UI View 项是否可能不再有效

转载 作者:搜寻专家 更新时间:2023-11-01 05:46:48 24 4
gpt4 key购买 nike

给定以下代码

@IBAction func buttonClick(_ sender: Any) {
recordLabel.text = "Perform some time consuming networking..."

let workItem = DispatchWorkItem {
// Perform some time consuming networking...

DispatchQueue.main.async {
// QUESTION: Is it possible, that the UI recordLabel is
// destroy/ invalid at this stage?
self.recordLabel.text = "Done"
}
}
DispatchQueue.global().async(execute: workItem)
}

这是

  1. 在用户线程中执行耗时的工作(如网络)
  2. 完成耗时工作后在 UI 线程中更新 UI

我想知道,在 UI 更新期间,是否有可能 UI 被破坏或不再有效?

原因是,对于 Android 生态系统,它们倾向于在用户线程执行过程中“重新创建”UI(参见 Best practice: AsyncTask during orientation change)。这使得用户线程持有的 UI 引用不再有效。

我想知道,iOS Swift 是否表现出类似的行为?

最佳答案

I was wondering, during UI updating, is there ever be a chance, that the UI is destroy, or no longer valid?

如果有问题的 View Controller 已被关闭,该 View 将从 View 层次结构中删除。但是,按照您编写此代码的方式,如果 View Controller 已被关闭,您的代码将更新一个不再可见的 View 。更糟糕的是,与您的 View Controller 及其 View 关联的内存在该分派(dispatch) block 完成之前不会被释放。这样做没有意义。

因此,如果我们要使用您的代码模式,您可以改为:

@IBAction func buttonClick(_ sender: Any) {
recordLabel.text = "Perform some time consuming networking..."

let workItem = DispatchWorkItem { // use `[weak self] in` pattern here, too, if you reference `self` anywhere
// Perform some time consuming networking...

DispatchQueue.main.async { [weak self] in
// Update the view if it’s still around, but don’t if not
self?.recordLabel.text = "Done"
}
}
DispatchQueue.global().async(execute: workItem)
}

或者,更自然地,

@IBAction func buttonClick(_ sender: Any) {
recordLabel.text = "Perform some time consuming networking..."

DispatchQueue.global().async { // use `[weak self] in` pattern here, too, if you reference `self` anywhere
// Perform some time consuming networking...

DispatchQueue.main.async { [weak self] in
// Update the view if it’s still around, but don’t if not
self?.recordLabel.text = "Done"
}
}
}

值得注意的是,通常不会将网络请求分派(dispatch)到全局队列,因为 URLSession、Alamofire 等网络库已经异步执行了它们的请求。所以你不会对全局队列进行 async 分派(dispatch)。

同样,如果这个网络请求只是为这个 View Controller 的 View 更新一些东西,你甚至可以在 View 被关闭时取消网络请求。 (为什么仅仅为了更新可能不再存在的 View 而继续执行网络请求?)这取决于请求的性质。

最后,当您解决这个紧迫的问题时,您可能会重新考虑 View Controller 是否应该发出网络请求,而不是其他类型的对象。这远远超出了这个问题的范围,但从长远来看需要重新考虑。

但是,如果不了解您在此向全局队列的调度中所做的事情,我们就无法对这些观察结果中的任何一个进行进一步评论。

关于ios - 在我们完成 DispatchWorkItem 并尝试使用 DispatchQueue.main.async 更新 UI 后,UI View 项是否可能不再有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56845425/

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