1. ホーム
  2. swift

Swiftで時限イベントをキャンセルする?

2023-10-03 10:09:42

質問

イベントから10秒後にコードのブロックを実行したいのですが、その10秒前に何かが起こった場合、10秒が過ぎたらコードが実行されないようにキャンセルできるようにしたいのですが、可能ですか?

これを使っているのですが、キャンセルできないんです。

static func delay(delay:Double, closure:()->()) {
  dispatch_after(
    dispatch_time(
      DISPATCH_TIME_NOW,
      Int64(delay * Double(NSEC_PER_SEC))
    ),
    dispatch_get_main_queue(), closure
  )
}

どうすれば実現できますか?

どのように解決するのですか?

これを試してみてください(Swift 2.x、Swift 3については下記のDavidの回答を参照してください)。

typealias dispatch_cancelable_closure = (cancel : Bool) -> ()

func delay(time:NSTimeInterval, closure:()->()) ->  dispatch_cancelable_closure? {

    func dispatch_later(clsr:()->()) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(time * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), clsr)
    }

    var closure:dispatch_block_t? = closure
    var cancelableClosure:dispatch_cancelable_closure?

    let delayedClosure:dispatch_cancelable_closure = { cancel in
        if let clsr = closure {
            if (cancel == false) {
                dispatch_async(dispatch_get_main_queue(), clsr);
            }
        }
        closure = nil
        cancelableClosure = nil
    }

    cancelableClosure = delayedClosure

    dispatch_later {
        if let delayedClosure = cancelableClosure {
            delayedClosure(cancel: false)
        }
    }

    return cancelableClosure;
}

func cancel_delay(closure:dispatch_cancelable_closure?) {
    if closure != nil {
        closure!(cancel: true)
    }
}

// usage
let retVal = delay(2.0) {
    println("Later")
}
delay(1.0) {
    cancel_delay(retVal)
}

こちらのWaamさんのコメントより。 dispatch_after - GCD in swift?