web-dev-qa-db-ja.com

Xcodeのメインスレッドチェッカーとは

Xcode 9ドキュメントの新機能を確認しましたが、これが見つかりました

enter image description here

しかし、新しいXcode 9でこれをどのように使用できるかはわかりませんでした。

12
Kishore Suthar

Appleドキュメント から:

メインスレッドチェッカーは、SwiftおよびC言語用のスタンドアロンツールであり、バックグラウンドスレッドでのAppKit、UIKit、およびその他のAPIの無効な使用を検出します。メインスレッド以外のスレッドのUIの更新はUI更新の欠落、視覚的な欠陥、データ破損、クラッシュを引き起こす可能性のある一般的な間違い。

したがって、たとえば、バックグラウンドスレッドでtextUILabelプロパティを変更しようとしても機能しません。 Appleは、これによりUI更新の欠落、視覚的欠陥、データ破損、クラッシュが発生する可能性があることを示しています。実際には、99%結果として、randomUI更新の欠落と視覚障害(クラッシュではない)が発生します。

UIKitのそのような不適切な使用を簡単に検出できるため、クラッシュは実際には良いでしょうが、ランダムな視覚的欠陥は開発中に検出するのがはるかに困難です。それがメインスレッドチェッカーの出番です。

メインスレッドチェッカーは、dectectバックグラウンドスレッドでのUIKitの使用に役立ちますが、それらを解決します。バックグラウンドスレッドでUIKitの使用を検出したら、DispatchQueueを使用して解決できます。

繰り返しになりますが、 Appleドキュメント

URLSessionのドキュメントには、完了クロージャーがバックグラウンドスレッドで呼び出されることが記載されているため、これは悪いことです。メインスレッドチェッカーは、バックグラウンドスレッドでUIKitの使用を検出するのに役立ちます。

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
   if let data = data {      
      self.label.text = "\(data.count) bytes downloaded"
      // Error: label updated on background thread   
   }
}
task.resume()

解決策:DispatchQueue.mainを使用して、メインスレッドでUIの更新を実行します。

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
   if let data = data {
      DispatchQueue.main.async { // Correct
         self.label.text = "\(data.count) bytes downloaded"
      }
   }
}
task.resume()

ソリューション自体はXcodeとは関係ありません。これは言語の機能です。したがって、明らかにXcodeの以前のバージョンでは可能でしたが、Xcode 9より前には、問題の検出に役立つメインスレッドチェッカーがありませんでした。

@hamishが指摘しているように、より詳細な説明については、 WWDCビデオ も見ることができます。

18
deadbeef

Runtime API Checkingセクションで、Main Thread Checkerが有効になっており、非UIスレッドでuiメソッドを実行しているかどうかを確認します。

enter image description here

enter image description here

0
Sh_Khan