Swift 3でディスパッチキューを作成する方法


403

Swift 2では、次のコードでキューを作成できました。

let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT)

しかし、これはSwift 3ではコンパイルされません。

Swift 3でこれを書くための好ましい方法は何ですか?



Swift 4には、シリアルキューを作成するための3つの追加パラメーターがあります。それらを使用してシリアルキューを作成する方法は?DispatchQueue.init(label:、qos:、attributes:、autoreleaseFrequency:、target:)
nr5

@ nr5キューはデフォルトでDispatchQueue(label: "your-label")シリアルであるため、シリアルキューに使用するだけで十分です。追加のパラメーターにはすべてデフォルト値があります。
jbg

回答:


1131

並行キューの作成

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}  

シリアルキューを作成する

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 

}

メインキューを非同期に取得する

DispatchQueue.main.async {

}

メインキューを同期的に取得する

DispatchQueue.main.sync {

}

バックグラウンドスレッドの1つを取得するには

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2ベータ2:

バックグラウンドスレッドの1つを取得するには

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

これらのキューの使用について知りたい場合は、この回答を参照してください


3
attributes: .serialシリアルキューを作成する場合、実際には省略できますlet serialQueue = DispatchQueue(label: "queuename")
キーン2016

15
Xcode 8ベータ4には.serialオプションがないため、属性の.concurrentを省略してシリアルキューを作成する必要があります。
Oleg Sherman

Swift3からobjcにDispatchQueueにアクセスする必要がありますが、次のエラーが発生しました。 = [SwiftClassキュー]; これは、swiftのDispatchQueueの静的変数です
ideerge

DispatchQueue.main.asynchronously(DispatchQueue.main){self.mapView.add(self.mapPolyline)} Swift 3.0でDispatchQueue.global()。asynchronously(DispatchQueue.main){self.mapView.add(self .mapPolyline)}ですが、どちらも「タイプdispathQuoueの値には非同期にメンバーがありません」と同じエラーを示します
Abirami Bala

1
OPのコードから、なぜ使用上のリンゴのフォーカスを行う「com.swift3.imageQueueを」。ラベルに3つの部分があることがわかります。何故ですか?各部分は何を表していますか?フォーマットがわかりません
Honey

55

> = Swift 3でコンパイルします。この例には、必要な構文のほとんどが含まれています。

QoS-新しいサービス品質構文

weak self -保持サイクルを中断する

自分が利用できない場合は、何もしない

async global utility queue-ネットワーククエリの場合、結果を待機せず、それは並行キューであり、ブロックは(通常)開始時に待機しません。並行キューの例外として、タスクの制限に以前に達した場合、キューは一時的にシリアルキューになり、そのキュー内の前のタスクが完了するまで待機します。

async main queue-UIに触れるため、ブロックは結果を待たずに、開始時にスロットを待ちます。メインキューはシリアルキューです。

もちろん、これにエラーチェックを追加する必要があります...

DispatchQueue.global(qos: .utility).async { [weak self] () -> Void in

    guard let strongSelf = self else { return }

    strongSelf.flickrPhoto.loadLargeImage { loadedFlickrPhoto, error in

        if error != nil {
            print("error:\(error)")
        } else {
            DispatchQueue.main.async { () -> Void in
                activityIndicator.removeFromSuperview()
                strongSelf.imageView.image = strongSelf.flickrPhoto.largeImage
            }
        }
    }
}

6
Swift 3でコーディングするときは、以前のコードの30%を
圧縮し

【弱い自己】例をありがとう!
imike

1
それはよりよくするのですguardものselfではありませんnil、それはだ場合、コードのいずれも実行されないように、上部にnil、例えば、guard strongSelf = self else { return }
Scott Gardner

@ t1 Swift 3のコードで書かれたGCDのドキュメントの場所を教えてください。私はObjective Cで書かれたものだけを見つけました。ここの誰かが私にWWDCのビデオを紹介してくれましたが、Swift 3の例を含む公式ドキュメントを読みたいのですが、見つける方法がありません。
bibcy 2016

1
.global(qos: .background)IO(ネットワーク要求)には使用しないでください。.global(qos: .default)または.global(qos: .utility)代わりに使用します。
ペドロパウロアモリ

28

XCode 8、Swift 3でコンパイル https://github.com/rpthomas/Jedisware

 @IBAction func tap(_ sender: AnyObject) {

    let thisEmail = "emailaddress.com"
    let thisPassword = "myPassword" 

    DispatchQueue.global(qos: .background).async {

        // Validate user input

        let result = self.validate(thisEmail, password: thisPassword)

        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if !result
            {
                self.displayFailureAlert()
            }

        }
    }

}

12

OPの質問はすでに上記で回答されているので、速度に関する考慮事項を追加したいだけです。

DispatchQueue.globalの非同期関数にどの優先クラスを割り当てるかによって、多くの違いが生じます。

特にタスクが低電力コアに割り当てられているように見えるiPhone Xで、.backgroundスレッド優先順位でタスクを実行することはお勧めしません。

以下は、XMLファイルから(バッファリングを使用して)読み取り、データ補間を実行する計算集中型関数からの実際のデータです。

デバイス名/ .background / .utility / .default / .userInitiated / .userInteractive

  1. iPhone X:18.7秒/ 6.3秒/ 1.8秒/ 1.8秒/ 1.8秒
  2. iPhone 7:4.6秒/ 3.1秒/ 3.0秒/ 2.8秒/ 2.6秒
  3. iPhone 5s:7.3s / 6.1s / 4.0s / 4.0s / 3.8s

データセットはすべてのデバイスで同じではないことに注意してください。iPhone Xで最大、iPhone 5sで最小です。


1
素晴らしい情報。助けてくれました
Morgz 2018

1
@Mykユーザーが開始した場合や結果を待っている場合は、.userInitiatedまたは.userInteractiveを使用して、他の操作をバックトラックする必要があります。他のほとんどの場合、.defaultが適切な選択です。
Cosmin

6

UITableViewやUIPickerViewのようにユーザーに気付かれずに新しいデータを表示するためにUIを更新する場合は、これが特に重要です。

    DispatchQueue.main.async
 {
   /*Write your thread code here*/
 }

3
 DispatchQueue.main.async {
          self.collectionView?.reloadData() // Depends if you were populating a collection view or table view
    }


OperationQueue.main.addOperation {
    self.lblGenre.text = self.movGenre
}

//ビューコントローラーにオブジェクト(ラベル、画像ビュー、テキストビュー)を入力する必要がある場合は、操作キューを使用します


2
   let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT) //Swift 2 version

   let concurrentQueue = DispatchQueue(label:"com.swift3.imageQueue", attributes: .concurrent) //Swift 3 version

私はあなたのコードをXcode 8、Swift 3で作り直し、変更はあなたのSwift 2バージョンとは対照的にマークされています。


これは私が書いたものよりもきれいに見えます。ありがとう。
gosborne3 2017年

2

スウィフト3

あなたは迅速なコードでいくつかのクロージャを呼び出したいなら、あなたはストーリーボードで変更したいです、あなたのアプリケーションがクラッシュするビューに属するタイプオフの変更

しかし、あなたはあなたのアプリケーションがクラッシュしないディスパッチメソッドを使用したいです

非同期メソッド

DispatchQueue.main.async 
{
 //Write code here                                   

}

同期方法

DispatchQueue.main.sync 
{
     //Write code here                                  

}

サービス呼び出し時にasyncメソッドを使用したいのですが、コードはDispatchQueue.main.async {let objstory1 = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController")as!です。HomeViewController _ = self.navigationController?.pushViewController(objstory1、animated:false)}
Amul4608

1
使用しないDispatchQueue.main.sync
trickster77777

メインキューの同期呼び出しは間違いなく問題を引き起こします。
豆腐戦士

2
DispatchQueue.main.async(execute: {

// write code

})

シリアルキュー:

let serial = DispatchQueue(label: "Queuename")

serial.sync { 

 //Code Here

}

同時キュー:

 let concurrent = DispatchQueue(label: "Queuename", attributes: .concurrent)

concurrent.sync {

 //Code Here
}

これはディスパッチキューを作成するのではなく、実行ループを1ティック経過した後にメインキューに追加するだけです。
ビルドは2017年


1
 let newQueue = DispatchQueue(label: "newname")
 newQueue.sync { 

 // your code

 }

1

Swift 5のアップデート

シリアルキュー

let serialQueue = DispatchQueue.init(label: "serialQueue")
serialQueue.async {
    // code to execute
}

同時キュー

let concurrentQueue = DispatchQueue.init(label: "concurrentQueue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)

concurrentQueue.async {
// code to execute
}

Appleのドキュメントから:

パラメーター

ラベル

Instruments、サンプル、スタックショット、およびクラッシュレポートなどのデバッグツールでキューを一意に識別するためにキューに添付する文字列ラベル。アプリケーション、ライブラリ、およびフレームワークはすべて独自のディスパッチキューを作成できるため、逆DNS命名スタイル(com.example.myqueue)をお勧めします。このパラメーターはオプションであり、NULLにすることができます。

QoS

キューに関連付けるサービス品質レベル。この値は、システムがタスクの実行をスケジュールする優先順位を決定します。可能な値のリストについては、DispatchQoS.QoSClassを参照してください。

属性

キューに関連付ける属性。タスクを同時に実行するディスパッチキューを作成するには、concurrent属性を含めます。この属性を省略すると、ディスパッチキューはタスクを順次実行します。

autoreleaseFrequency

キューがスケジュールするブロックによって作成されたオブジェクトを自動解放する頻度。可能な値のリストについては、DispatchQueue.AutoreleaseFrequencyを参照してください。

目標

ブロックを実行するターゲットキュー。現在のオブジェクトに適したキューをシステムに提供させる場合は、DISPATCH_TARGET_QUEUE_DEFAULTを指定します。


-3

今では簡単です:

let serialQueue = DispatchQueue(label: "my serial queue")

デフォルトはシリアルです。並行して取得するには、オプションの属性引数.concurrentを使用します。


を追加して、回答を更新することをお勧めしますseiralQueue.async {}。@tylemol
DawnSong

-3
DispatchQueue.main.async(execute: {
   // code
})

このコードスニペット、ありがとうございます。適切な説明は、なぜこれが問題の優れた解決策であるを示すことによって教育的価値を大幅に改善し、同様の、しかし同一ではない質問を持つ将来の読者にとってより有用になります。回答を編集して説明を追加し、適用される制限と前提を示してください。
Toby Speight 2017年

-4

あなたはSwift 3.0でこのコードを使用してディスパッチキューを作成できます

DispatchQueue.main.async
 {
   /*Write your code here*/
 }

   /* or */

let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)                   
DispatchQueue.main.asyncAfter(deadline: delayTime)
{
  /*Write your code here*/
}

1
申し訳ありませんが、それはディスパッチキューを作成していません。実行ループを1ティック経過した後、メインキューにアクセスしています。
ビルドは2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.