Help us understand the problem. What is going on with this article?

SwiftのGCDで最新のキューだけを処理し続ける

More than 1 year has passed since last update.

重たい画像処理のパラメータをGUI Sliderで操作しつつ結果をプレビューしたいとき、
画像処理にかかる時間よりもGUIからイベントが送られて来る間隔の方が圧倒的に短くて

  • 同期処理だとUIがカクカクする
  • 非同期直列処理だとプレビューへの反映が遅い
  • 非同期並列処理だとプレビューが最新であることが保証されない

という問題にぶちあたった。

UIをストレスなく操作させつつなるべく最新の結果をプレビューできるようにするためには

  • 非同期処理
  • 処理中に溜まっていくタスクは最新のもののみ保持して残りは捨てる

という実装がよさそう。
ということでできたものがこちらです。

Swift3.0
class ViewController: UIViewController {
    // 同時実行数を1に制限するためのセマフォ
    let semaphore = DispatchSemaphore(value:1)
    let queue = DispatchQueue(label: "imageproc", qos:.userInteractive)
    var workItem : DispatchWorkItem?

    // このハンドラがえげつない回数呼ばれる
    @IBAction func imageProc(_ sender: Any) {
        // 前回追加したタスクが未処理の場合はキャンセルされる
        workItem?.cancel()

        workItem = DispatchWorkItem {
            // 処理中のタスクがある場合は待つ
            self.semaphore.wait()
            self.imageProcImpl()
            // プレビューへの反映はメインスレッドで
            DispatchQueue.main.async {
                self.imageProcAfter()
                // プレビューへの反映が終わってからセマフォを解放
                self.semaphore.signal()
            }
        }
        // キューに追加
        queue.async(execute: workItem!)
    }
    func imageProcImpl() {
        // 重たい画像処理
    }
    func imageProcAfter() {
        // プレビューに反映
    }
}
nariakiiwatani
インタラクティブコンテンツのプログラマ。「技術的な興味を突き詰めると思いやりが生まれる」と「プログラマにもっとも重要な能力は気遣いと思いやりである」がモットー。コンテンツに触れるお客さんにも一緒に作品を作るコラボレーターにも制作の機会をくれるクライアントにも優しいプログラミングを心がけている。2012年4月に大学院時代の仲間たちと株式会社anno labを設立。九州大学大学院 芸術工学府修了。
http://annolab.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした