474

Swift 2 では、dispatch_afterグランド セントラル ディスパッチを使用してアクションを遅らせることができました。

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

しかし、これはSwift 3以降コンパイルされないようです.これを現代のSwiftで書くための好ましい方法は何ですか?

4

12 に答える 12

1169

構文は次のとおりです。

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

secondsa として追加する上記の構文はDouble、混乱の原因のように思われることに注意してください (特に、nsec を追加することに慣れているため)。その「add seconds as Double」構文が機能するdeadlineのは、 is a DispatchTimeand であり、舞台裏で aを取り、その秒数を に追加+する演算子があるためです。DoubleDispatchTime

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

しかし、本当に msec、μs、または nsec の整数を に追加したい場合は、 aに a をDispatchTime追加することもできます。つまり、次のことができます。DispatchTimeIntervalDispatchTime

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m μs seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}

これらはすべてシームレスに機能します。これは、クラス+内の演算子に対するこの個別のオーバーロード メソッドのおかげです。DispatchTime

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime

ディスパッチされたタスクをキャンセルする方法について尋ねられました。これを行うには、 を使用しますDispatchWorkItem。たとえば、これは 5 秒で起動するタスクを開始します。または、View Controller が閉じられて割り当てが解除されるとdeinit、タスクがキャンセルされます。

class ViewController: UIViewController {

    private var item: DispatchWorkItem?

    override func viewDidLoad() {
        super.viewDidLoad()

        item = DispatchWorkItem { [weak self] in
            self?.doSomething()
            self?.item = nil
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
    }

    deinit {
        item?.cancel()
    }

    func doSomething() { ... }

}

[weak self]でのキャプチャ リストの使用に注意してくださいDispatchWorkItem。これは、強い参照サイクルを回避するために不可欠です。また、これはプリエンプティブなキャンセルを行うのではなく、タスクがまだ開始されていない場合は開始を停止するだけであることに注意してください。ただし、呼び出しに遭遇するまでに既に開始されている場合cancel()、ブロックは実行を終了します (ブロック内を手動でチェックしていない限りisCancelled)。

于 2016-06-14T01:31:08.670 に答える
130

スウィフト 4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

当面の間.seconds(Int).microseconds(Int).nanoseconds(Int)も使用される場合があります。

于 2016-06-17T22:27:12.203 に答える
61

遅延機能だけが必要な場合

スイフト 4 & 5

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
     DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
          closure()
     }
}

次のように使用できます。

delay(interval: 1) { 
    print("Hi!")
}
于 2016-07-29T07:09:46.140 に答える
3

Swift 4.1 および Xcode 9.4.1 では

簡単な答えは...

//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
于 2018-08-18T06:11:29.263 に答える
3

スイフト5以上

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
   // code to execute                 
})
于 2019-04-24T12:07:07.730 に答える
3

電話DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

Xcode ツールを使用して Swift 3 に変換することを強くお勧めします ([編集] > [変換] > [現在の Swift 構文に])。それは私のためにこれを捕まえました

于 2016-06-14T01:12:40.417 に答える
0

try this

let when = DispatchTime.now() + 1.5
    DispatchQueue.main.asyncAfter(deadline: when) {
        //some code
    }
于 2017-11-07T12:58:35.333 に答える