遅延実行/遅延処理
所定の時間が経過した後に、特定の処理を遅延実行させたいような場合はNSTimerやGCDによるタイマー処理を用いることができます。
最近はGCDの利用が好まれる傾向にあります(循環参照の問題には注意する必要があります)。NSTimerは昔からよく使われている方法で、タイマーの延長や取り消しなども可能です。performSelector:withObject:afterDelay:は簡易的に遅延評価を実現する方法としては便利に使えます。
GCD (Grand Central Dispatch)
AppleのiOS/macOS開発環境等で利用できます。
Objective-C, C言語, C++
// #include <dispatch/dispatch.h>
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
printf("3秒後に呼ばれます");
});
printf("先に呼ばれます");
Swift 3.0以降
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
print("3秒後に呼ばれます");
}
Swift
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
print("3秒後に呼ばれます");
}
NSTimer
指定した時間が経過すると、target
に指定されたインスタンスに対してselector
で指定されたメッセージが投げられます。
Objective-C
- (void)main {
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(hello:) userInfo:nil repeats:NO];
printf("先に呼ばれます");
}
- (void)hello:(NSTimer *)timer {
printf("3秒後に呼ばれます");
}
Swift
func main() {
NSTimer.scheduledTimerWithTimeInterval(3.0, target: self, selector: #selector(hello(_:)), userInfo: nil, repeats: false)
print("先に呼ばれます");
}
func hello(timer: NSTimer) { print("3秒後に呼ばれます"); }
[NSObject performSelector:withObject:afterDelay:]
NSTimerの代わりにperformSelector:withObject:afterDelay:
メソッドを用いる方法もあります。Objective-Cオブジェクト自身のメソッドを遅延実行させることができます。
// 3秒後に`[@"a" isEqualToString:@"a"]`と同等の呼び出しが行われる
/* Objective-C */
[@"a" performSelector:@selector(isEqualToString:) withObject:@"b" afterDelay:3.0];
/* Swift */
("a" as NSString).performSelector(#selector(NSString.isEqualToString(_:)), withObject: "a", afterDelay: 3.0)