iOS15にアップデートした端末でテストしていると、
iOS14では問題なかった箇所でクラッシュしていました。
UIViewControllerRepresentableで使用しているViewControllerで
viewDidLoad内でaddSubviewしたタイミングでメモリ排他アクセスが出来ておらずクラッシュします。
エラーメッセージは以下の通りです。
Simultaneous accesses to 〜, but modification requires exclusive access error
問題箇所
実際のコードでは分かりにくいので省略・改変しています。
このコードで起きるかは分からないのでご注意ください。
struct WrapperView: UIViewControllerRepresentable {
typealias UIViewControllerType = WrapperView
func makeUIViewController(context: Context) -> UIViewControllerType {
let vc = ViewController()
//初期化処理(略)
return vc
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
//更新処理(略)
}
}
class ViewController:UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
webView.translatesAutoresizingMaskIntoConstraints = false
//ここのaddSubviewで落ちる
self.view.addSubview(self.tabWebObj)
webView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
webView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
webView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
webView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
SwiftUIが描画を行う際にviewDidLoadを呼び出した時、
複数回呼ばれてクラッシュしていました。
どうやら画面を再構成する際に並行して同じViewControllerのviewDidLoadが走っている様です。
解決策
メモリに同時アクセスしているのが問題なので同一スレッドで処理させます。
描画関係の処理なのでDispatchQueue.mainに投げてしまいます。
class ViewController:UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
webView.translatesAutoresizingMaskIntoConstraints = false
DispatchQueue.main.async {
self.view.addSubview(self.tabWebObj)
webView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
webView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
webView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
webView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
}
あまり気持ちの良い解決策ではありませんが、
iOS15からである事と、アプリがクラッシュする為、
暫定的にこの対応をしました。
コメント