メインスレッドに影響を与えないように、バックグラウンドスレッドでいくつかのビューをレンダリングしようとしています。それはXcode 9以前では決して問題ではありませんでした。
DispatchQueue.global(qos: .background).async {
let customView = UIView(frame: .zero)
DispatchQueue.main.async {
self.view.addSubview(customView)
}
}
UIView.init(frame :)はメインスレッドからのみ使用する必要があります
このエラーは2行目で発生します。
更新
Apple UIView
ドキュメンテーションは、実際にはThreading Considerationsセクションで述べています:
アプリケーションのユーザーインターフェースの操作は、メインスレッドで行う必要があります。したがって、アプリケーションのメインスレッドで実行されているコードからUIViewクラスのメソッドを常に呼び出す必要があります。 これが厳密に必要でない場合は、ビューオブジェクト自体を作成するときだけですが、他のすべての操作はメインスレッドで行う必要があります。
Xcode 9には、新しいランタイムメインスレッドチェッカーがあり、バックグラウンドスレッドからUIKitの呼び出しを検出して警告を生成します。
アプリをクラッシュさせるのではなく、警告を生成することを意図していますが、テストターゲットのメインスレッドチェッカーを無効にしてみてください。
サンプルプロジェクトでこのコードを試してみましたが、デバッガーは問題で一時停止しました(想定どおり)が、アプリはクラッシュしませんでした。
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
let v = UIView(frame: .zero)
}
}
この機能を使用できます
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)
次のようにメインスレッドを入力できます
DispatchQueue.main.async {
// UIView usage
}