1. ホーム
  2. swift

[解決済み] Swift 3、Swift 4、それ以降で dispatch_sync, dispatch_async, dispatch_after などはどうすればいいですか?

2022-03-04 11:09:34

質問内容

私は、Swift 2.x (あるいは 1.x) のプロジェクトに、次のようなコードをたくさん持っています。

// Move to a background thread to do some long running work
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    let image = self.loadOrGenerateAnImage()
    // Bounce back to the main thread to update the UI
    dispatch_async(dispatch_get_main_queue()) {
        self.imageView.image = image
    }
}

実行を遅らせるためにこんなのも。

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
    print("test")
}

Grand Central Dispatch API の他のあらゆる種類の使用法....

今、私はSwift 3用のXcode 8 (ベータ)で私のプロジェクトを開いたところ、あらゆる種類のエラーが表示されます。それらのいくつかは、私のコードを修正することを提供しますが、修正のすべてが動作するコードを生成するわけではありません。私はこれについてどうしたらいいでしょうか?

解決方法は?

Swiftは当初からObjCやCをよりSwiftyにするための機能をいくつか提供し、バージョンアップごとに追加してきました。さて、Swift 3では、新しい "import as member" 機能により、あるスタイルの C API を持つフレームワーク (クラスのように動作するデータ型と、それを操作するグローバル関数の束を持っている) が、より Swift ネイティブ API のように動作するようになります。データ型は Swift のクラスとしてインポートされ、関連するグローバル関数はそれらのクラスのメソッドとプロパティとしてインポートされ、定数のセットのようないくつかの関連するものは適切な場所でサブタイプになることができます。

Xcode 8 / Swift 3 beta では、Apple はこの機能を(他のいくつかの機能とともに)適用し、Dispatch フレームワークをより Swifty にしています。(そして コアグラフィックス も、そうです)。Swiftのオープンソースの取り組みを見ていると これはニュースではない が、Xcodeの一部になるのは今回が初めてです。

プロジェクトをSwift 3に移行するための最初のステップ は、Xcode 8 で開き、次のように選択する必要があります。 編集 > 変換 > 現在のSwift構文に... をクリックします。これにより、API名の変更などに必要なすべての変更が一度に適用されます(あなたのレビューと承認を得て)。(多くの場合、1つのコード行は一度に複数の変更の影響を受けるので、個別にエラーフィクスイットに対応すると、すべてを正しく処理できない可能性があります)

その結果、よくある裏方への仕事のバトンタッチのパターンは、現在では次のようになります。

// Move to a background thread to do some long running work
DispatchQueue.global(qos: .userInitiated).async {
    let image = self.loadOrGenerateAnImage()
    // Bounce back to the main thread to update the UI
    DispatchQueue.main.async {
        self.imageView.image = image
    }
}

ここでは .userInitiated の代わりに、古い DISPATCH_QUEUE_PRIORITY という定数があります。QoS (Quality of Service) 指定子は OS X 10.10 / iOS 8.0 で導入され、システムが仕事の優先順位を決める明確な方法を提供し、古い優先順位指定子は非推奨になりました。Apple の バックグラウンドワークとエネルギー効率に関するドキュメント をご覧ください。

ところで、仕事を整理するために自分でキューを管理している場合、キューを取得する方法は次のようになります。 DispatchQueueAttributesOptionSet そのため、オプションを組み合わせるにはコレクションスタイルのリテラルを使用します)。

class Foo { 
    let queue = DispatchQueue(label: "com.example.my-serial-queue",
                           attributes: [.serial, .qosUtility])
    func doStuff() {
        queue.async {
            print("Hello World")
        }
    }
}

使用方法 dispatch_after を後で作業する?それはキュー上のメソッドでもあり、キューから DispatchTime この演算子にはさまざまな数値の型があり、秒の整数や端数を足すことができます。

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // in half a second...
    print("Are we there yet?")
}

新しい Dispatch API の使い方は、Xcode 8 でそのインターフェイスを開くことでわかります -- Open Quickly を使って Dispatch モジュールを見つけるか、シンボル(例えば DispatchQueue をクリックし、そこからモジュール内をブラウズしてください。(あなたは、Swift の ディスパッチ Appleの新しいAPIリファレンスサイトとXcodeドキュメントビューアーにあるAPIですが、Cバージョンのドキュメントコンテンツはまだそこに移動していないようです(笑)。

をご覧ください。 移行ガイド をご覧ください。