ios Xcode UIView.init(frame:) 只能在主线程中使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46362641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Xcode UIView.init(frame:) must be used from main thread only
提问by Lukas Würzburger
I'm trying to render some views in background thread to not affect the main thread. That was never a problem before Xcode 9.
我试图在后台线程中呈现一些视图以不影响主线程。在 Xcode 9 之前,这从来都不是问题。
DispatchQueue.global(qos: .background).async {
let customView = UIView(frame: .zero)
DispatchQueue.main.async {
self.view.addSubview(customView)
}
}
UIView.init(frame:) must be used from main thread only
UIView.init(frame:) 只能在主线程中使用
This error occurs in the second line.
此错误发生在第二行。
Update
更新
The Apple UIView
Documentation actually says in the Threading Considerationssection:
苹果UIView
文档实际上在线程注意事项部分说:
Manipulations to your application's user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself, but all other manipulations should occur on the main thread.
对应用程序用户界面的操作必须发生在主线程上。因此,您应该始终从应用程序主线程中运行的代码调用 UIView 类的方法。这可能不是绝对必要的唯一时间是在创建视图对象本身时,但所有其他操作都应该在主线程上进行。
采纳答案by Puneet Sharma
Xcode 9 has a new runtime Main Thread Checkerthat detects call to UIKit from a background thread and generate warnings.
Xcode 9 有一个新的运行时主线程检查器,它检测从后台线程对 UIKit 的调用并生成警告。
I know its meant to generate warnings and not crash the app, but you can try disabling Main Thread Checker for your test target.
我知道它的目的是生成警告而不是使应用程序崩溃,但是您可以尝试为您的测试目标禁用主线程检查器。
I tried this code in a sample project, the debugger paused at the issue (as it is supposed to), but the app didn't crash.
我在一个示例项目中尝试了这段代码,调试器在这个问题上暂停了(正如它应该的那样),但应用程序没有崩溃。
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
let v = UIView(frame: .zero)
}
}
回答by Erhan Demirci
You can use this function
你可以使用这个功能
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()
}
How to use this function?
如何使用这个功能?
downloadImage(urlstr: "imageUrl", imageView: self.myImageView)
回答by Aditya A.Rajan
Main Thread Entry
主线程入口
You can enter the main thread as follows
可以按如下方式进入主线程
DispatchQueue.main.async {
// UIView usage
}