[解決済み] Swift 3, 4, 5 で dispatch_after GCD を書くにはどうしたらいいですか?
質問
Swift2において、私は
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でこれを書くには、どのような方法が望ましいのでしょうか?
どのように解決するのですか?
構文は簡単です。
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
なお、上記の構文で
seconds
として
Double
が混乱の元になっているようです(特に私たちはnsecを追加することに慣れていたので)。その "秒を追加するとして
Double
という構文が機能するのは
deadline
は
DispatchTime
と、その裏側には
+
演算子で
Double
に、その秒数を加算します。
DispatchTime
:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
しかし、どうしてもmsec、μs、nsecの整数を追加したい場合は
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秒後に発火するタスクを開始します。あるいは、ビューコントローラが棄却されて割り当て解除された場合、その
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
を使用します)。
関連
-
[解決済み] dispatch_after - GCD in Swift?
-
[解決済み] Swift 3、Swift 4、それ以降で dispatch_sync, dispatch_async, dispatch_after などはどうすればいいですか?
-
[解決済み] アトミック属性と非アトミック属性の違いは何ですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Swiftでindexとelementでループを反復させる方法
-
[解決済み] iphoneアプリのベータテストはどのように行うのですか?
-
[解決済み] SwiftでiOSキーボードを任意の場所でタッチして閉じる
-
[解決済み] Swift 3でディスパッチキューを作成する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] UITableViewの選択を無効にするにはどうすればよいですか?
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] Xcode 6のバグ:Interface Builderファイル内の不明なクラス
-
[解決済み] NSの接頭辞はどういう意味ですか?
-
[解決済み] UITextFieldのテキスト変更イベント
-
[解決済み] iPhone 5の画面解像度に対応したアプリを開発・移行するには?
-
[解決済み] NSOperationとGrand Central Dispatchの比較
-
[解決済み] アプリのプレビュー用にiOSシミュレータのビデオをキャプチャー
-
[解決済み] iOSとWatchKitで画像のtintColorを変更する方法
-
[解決済み] iOSで現在のデバイスの言語を取得するには?