我正在尝试在后台线程中渲染一些视图,以免影响主线程。在Xcode 9之前,这从来都不是问题。
DispatchQueue.global(qos: .background).async {
let customView = UIView(frame: .zero)
DispatchQueue.main.async {
self.view.addSubview(customView)
}
}
UIView.init(frame :)必须仅在主线程中使用
第二行发生此错误。
更新
Apple UIView
文档实际上在线程注意事项部分中说明了:
必须在主线程上对应用程序的用户界面进行操作。因此,您应该始终从应用程序主线程中运行的代码调用UIView类的方法。 这可能不是绝对必要的唯一时间是创建视图对象本身,但所有其他操作应该在主线程上发生。
答案 0 :(得分:25)
Xcode 9有一个新的运行时 Main Thread Checker ,用于检测后台线程对UIKit的调用并生成警告。
我知道它的意思是生成警告并且不会使应用程序崩溃,但您可以尝试为您的测试目标禁用主线程检查器。
我在一个示例项目中尝试了这个代码,调试器在问题上暂停(正如它应该的那样),但应用程序没有崩溃。
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
let v = UIView(frame: .zero)
}
}
答案 1 :(得分:15)
您可以使用此功能
func downloadImage(urlstr: String, imageView: UIImageView) {
let url = URL(string: urlstr)!
let task = URLSession.shared.dataTask(with: url) { data, _, _ in
guard let data = data else { return }
DispatchQueue.main.async { // Make sure you're on the main thread here
imageview.image = UIImage(data: data)
}
}
task.resume()
}
如何使用此功能?
downloadImage(urlstr: "imageUrl", imageView: self.myImageView)
答案 2 :(得分:2)
DispatchQueue.main.async {
// UIView usage
}