Doe*_*ata 5 user-interface multithreading ios swift
我读过 UI 应该总是在主线程上更新。但是,当谈到实现这些更新的首选方法时,我有点困惑。
我有各种函数来执行一些条件检查,然后结果用于确定如何更新 UI。我的问题是整个函数应该在主线程上运行吗?应该只更新用户界面吗?我可以/应该在另一个线程上运行条件检查吗?它是否取决于功能的作用或您希望它完成的速度?
示例一个在没有线程的情况下更改 ImageView 中的图像的函数:
@IBAction func undoPressed(_ sender: Any) {
if !previousDrawings.isEmpty {
previousDrawings.remove(at: previousDrawings.count - 1)
if let lastDrawing = previousDrawings.last {
topImageView.image = lastDrawing
}
else {
// empty
topImageView.image = nil
}
}
}
Run Code Online (Sandbox Code Playgroud)
我应该topImageView.image在主线程上设置吗?像这样:
@IBAction func undoPressed(_ sender: Any) {
if !previousDrawings.isEmpty {
previousDrawings.remove(at: previousDrawings.count - 1)
if let lastDrawing = previousDrawings.last {
DispatchQueue.main.async {
self.topImageView.image = lastDrawing
}
}
else {
DispatchQueue.main.async {
self.topImageView.image = nil
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我应该使用后台线程进行条件检查吗?像这样:
@IBAction func undoPressed(_ sender: Any) {
DispatchQueue.global(qos: .utility).async {
if !previousDrawings.isEmpty {
previousDrawings.remove(at: previousDrawings.count - 1)
if let lastDrawing = previousDrawings.last {
DispatchQueue.main.async {
self.topImageView.image = lastDrawing
}
}
else {
DispatchQueue.main.async {
self.topImageView.image = nil
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果有人能解释什么方法是首选的,为什么那会很有帮助。
备份。除特殊情况外,您的所有代码都在主线程上运行。UIAction例如,方法总是在主线程上执行,所有方法都是由UIViewController它的各种子类定义的。事实上,您可以放心地说 UIKit 方法是在主线程上执行的。同样,您的方法只会在非常特殊的情况下在后台线程上调用,这些情况有很好的记录。
您可以使用 GCD 在后台线程上运行代码块。在这种情况下,代码正在后台线程上运行,因为您明确要求这样做。
一些系统函数(如URLSession)默认调用它们的委托方法/在后台线程上运行它们的完成处理程序。这些都是有据可查的。对于像 AlamoFire 或 FireBase 这样的第三方库,您必须阅读文档,但是在后台线程上调用的任何代码都应该有很好的文档记录,因为您必须对在后台线程上运行的代码采取特殊的预防措施。
使用后台线程的通常原因是,长时间运行的任务可以运行到完成,而不会冻结用户界面,直到它完成。
例如,一个常见的模式是使用从远程服务器URLSession读取一些JSON数据。完成处理程序在后台线程上调用,因为解析返回的数据可能需要时间。但是,一旦您完成解析它,您将在主线程的 GCD 调用中包装更新 UI 的调用,因为必须在主线程上执行 UI 更改。
首先,您的undoPressed方法将在主队列上调用。
在第一组代码中,所有内容都将位于主队列上。
在第二组代码中,使用DispatchQueue.main.async是没有意义的,因为其余代码已经在主队列上。
所以实际上你唯一的两个明智的选择是 1 和 3。
根据您的代码,选项 1 就可以了。仅当后台运行的代码执行时间不长时,您才需要使用选项 3。由于这里的代码很简单并且几乎不需要时间来执行,因此选项 3 在这里没有意义。
因此,只需使用您的第一组代码就可以了。
当需要执行大循环或计算复杂算法或执行任何类型的网络访问时,请担心将代码移至后台。
| 归档时间: |
|
| 查看次数: |
11968 次 |
| 最近记录: |