LoginSignup
25
23

More than 5 years have passed since last update.

非同期処理で早く処理が終わっても最低でも◯秒は待たせる

Last updated at Posted at 2015-10-01
  • 2016/03/10 コードを修正

非同期で処理を行うときに、◯秒未満で処理が終わってしまうときは◯秒待つまで待たせてメインスレッドに処理を戻すようにして、
◯秒以上かかるときは通常通り処理が終わり次第メインスレッドに処理を戻すようにしたい場面があったので、関数化して使えるようにしました。

コード1

func wait_atleast(time : NSTimeInterval, @noescape _ block: () -> Void) {
    let start = CFAbsoluteTimeGetCurrent()
    block()
    let end = CFAbsoluteTimeGetCurrent()
    let wait = max(0.0, time - (end - start))
    if wait > 0.0 {
        NSThread.sleepForTimeInterval(wait)
    }
}

処理にかかった時間と、最低でも◯秒待って欲しいと指定した時間の差を取って、残り待ち時間があればsleepをかけて、
がなければそのまま、といった感じです。
待ち時間を最低5秒と設定した場合、

  • 処理が3秒しかかからなかった→2秒待つ
  • 処理が6秒かかった→待ち時間を超えているのでsleepはかけない

となります。

循環参照について

引数で渡すClosureに対して@noescapeを指定しているため、この処理に関してはselfをキャプチャする必要はありません。

△-キャプチャは不要
wait_atleast(1.0) { [weak self] in
    self?.hoge = ""
}

※ただ、dispatch_asyncとセットで用いる事になると思うので、dispatch_asyncでのClosureに対しては weak/unowned でのキャプチャが必要です。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { [weak self] in
    self?.hoge = "hoge"
    wait_atleast(1.0) { // ここで [weak self] in は不要
        self?.hoge = "fuga" // @noescapeではあるが、`dispatch_async`の範囲内なので、`self?.`は必要
    }
}

使用例

例えば非同期で何か処理を行うときに、すぐ終わる時もあれば、数秒かかる時もあるような場合で、
HUD(例だとSVProgressHUD)を表示して処理を行うが、すぐ終わるときにHUDがすぐに消えてしまって
ユーザーにHUDで表示した文字を認識してもらえない場合もあったりします。。
(表示がでてすぐ消えちゃうと、なんだなんだ?ってなるので)
そんなときにもしすぐ処理が終わっても、1秒は待たせるときは、以下のように記述します。

example
    SVProgressHUD.showWithStatus("保存中です...")
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { [weak self] in
        wait_atleast(1.0) {
            self?.saveImage()
        }
        dispatch_async(dispatch_get_main_queue()) {
            SVProgressHUD.showSuccessWithStatus("保存しました")
        }
    }

端末の処理速度、処理の時の条件によっては早かったり遅かったりする時間を最低◯秒は非同期処理しているように見せることができるので、
場合によってはアリなのかなって思います(ごまかしたりできるので)。


  1. NSDate()から、CFAbsoluteTimeGetCurrent()に変更しました。 

25
23
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
23