構文は次のとおりです。
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
seconds
a として追加する上記の構文はDouble
、混乱の原因のように思われることに注意してください (特に、nsec を追加することに慣れているため)。その「add seconds as Double
」構文が機能するdeadline
のは、 is a DispatchTime
and であり、舞台裏で aを取り、その秒数を に追加+
する演算子があるためです。Double
DispatchTime
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
しかし、本当に msec、μs、または nsec の整数を に追加したい場合は、 aに a をDispatchTime
追加することもできます。つまり、次のことができます。DispatchTimeInterval
DispatchTime
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
)。