2017-06-02 6 views
23

私はDispatchQueue.main.asyncを使用していましたが、UI関連の操作を実行するのに長い時間がかかりました。 しかし、SwiftはDispatchQueue.main.asyncとDispatchQueue.main.syncを提供し、両方がメインキューで実行されます。 だから誰も私の違いを教えてくれる? いつ使うべきですか? ありがとうございます。DispatchQueue.main.asyncとDispatchQueue.main.syncの相違点

 DispatchQueue.main.async { 
      self.imageView.image = imageView 
      self.lbltitle.text = "" 

     } 
     DispatchQueue.main.sync { 
      self.imageView.image = imageView 
      self.lbltitle.text = "" 

     } 

答えて

44

なぜ並行処理? データを読み込むなどのタスクを重労働に追加すると、UIの処理が遅くなったり、フリーズすることさえあります。 並行処理では、2つ以上のタスクを同時に実行できます。 このアプローチの欠点はスレッドの安全性であり、必ずしも制御するのが容易ではありません。 F.e.異なるタスクが、異なるスレッド上の同じ変数を変更しようとするか、または異なるスレッドによって既にブロックされているリソースにアクセスしようとするような、同じリソースにアクセスしたい場合。

私たちが知る必要がある抽象概念はいくつかあります。

  • キュー。
  • 同期/非同期タスクのパフォーマンス。
  • 優先度。
  • 一般的なトラブル。

キュー

またはとする必要があります。同様にグローバルまたはプライベートと同時に。

シリアルキューのタスクは1つずつ完了し、同時キューのタスクは同時に実行され、予期しないスケジュールで終了します。同じグループのタスクは、並行キューと比較してシリアルキュー上の時間が長くなります。

自分プライベートキューを(シリアルまたは同時両方)を作成したり、グローバル(システム)キューすでに利用可能なを使用することができます。 メインキューのみは、グローバルキューのうち、シリアルのいずれかです。

非常未凍結とに応じてUIを維持するために(ネットワークからFE負荷データ)メインキュー上のUIの仕事と呼ばれますが、他のキューにされていない重いタスクを実行しないことをお勧めしますユーザーアクション。他のキューでUIを変更すると、予期しない別のスケジュールと速度で変更が行われるため、必要な前にUIエレメントを描画したり、遅すぎたりすることがあります。 UIをクラッシュさせる可能性があります。また、グローバルキューシステムキューであるため、システムによって実行できる他のタスクがいくつかあることに留意する必要があります。


サービス品質/優先度。を.userInitiated

メインキュー - - のための
.userInteractive

キューは、異なるなQoS(サービス品質)(ここでは最高から最低まで)優先を実行するタスクを設定を持っていますユーザーが何らかの応答を待つタスクを開始しました
.utility - 時間がかかり、即座に応答する必要のないタスクについては、たとえばデータを使用して作業します。
.background - 視覚的な部分に関連しておらず、完了時間に関して厳しくないタスクのために)。



.defaultキューは
情報をに転送しません。 のQoS.userInitiated.utilityの間で使用されますQoSを検出することができなかった場合。

タスクが同期または非同期を行うことができます。

  • 同期機能は、タスクが終了した後にのみ、現在のキュー上のコントロールを返します。キューをブロックし、タスクが終了するまで待ちます。

  • 非同期関数が戻ると、タスクが別のキュー上で実行されるために送信された直後に現在のキューに制御します。タスクが終了するまで待機しません。キューをブロックしません。

共通の悩み。

同時アプリケーションを投影しながら、プログラマが作る最も人気のある過ちは次のとおりです。

  • レース条件 - アプリの作業は、コード部分の実行の順序に依存したときに発生します。
  • 優先順位の逆転 - 小さい優先度のタスクが何らかのリソースに仕上がっているの優先度の高いタスクの待ちがデッドロック
  • をブロックされている - いくつかのキューは無限ソース(変数、データなどを待っているとき、 )がすでにこれらのキューの一部によってブロックされています。

メインキューでは同期機能を呼び出さないでください。
メインキューでsync関数を呼び出すと、キューがブロックされます。キューはタスクの完了を待っていますが、タスクが完了するまで待つことはありません。キューは既にブロックされています。 デッドロックと呼ばれます。

同期を使用するタイミングは? タスクが終了するまで待つ必要があるとき。 F.e.いくつかの関数/メソッドがダブルコールされていないことを確認しているとき。 F.e.私たちは同期を取り、それが完全に終了するまでそれが二重に呼ばれるのを防ぐようにしています。
How to find out what caused error crash report on IOS device?

+0

いつ同期を呼び出す必要がありますか? –

+0

あなたは同じものの例を教えてください。 –

+0

私は答えを更新しました。更新されたバージョンをチェックしてください。 – Alexander

9

asyncを使用すると、ディスパッチされたブロックが実行されるまで待機せずに呼び出しキューを動かすことができます。反対にsyncは呼び出し元のキューを停止し、ブロック内でディスパッチした作業が完了するまで待機します。したがって、syncはデッドロックにつながる可能性があります。 DispatchQueue.main.syncをメインキューから実行してください。呼び出し元のキューは、ディスパッチされたブロックが終了するまで待機しますが、キューが停止して待機しているため待機しないため、フリーズします。

sync?あなたが別のキューで行わ何かを待つだけにして、あなたの現在のキュー上の同期を使用しての

例作業を継続する必要がある場合:シリアルキューに

を、あなたは確かにするために、ミューテックスとしてsync使用することができます同時に1つのスレッドしか保護されたコードを実行することはできません。

+0

同じような例を教えてください。 –

+0

同期の使用例? –

+0

はい。同期の使い方は? –

関連する問題