performSelector && NSTimer
使用performSelector系列的方法就是對NSTimer的一種封裝,所以NSTimer需要注意的地方,就是performSelector需要注意的地方。
一般可以使用
[self performSelector:@selector(showAlertView) withObject:nil afterDelay:5];
但是要注意這個系列還有一個方法
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray<NSRunLoopMode> *)modes;
對NSTimer而言,默認是在NSDefaultRunLoopMode模式下面執(zhí)行,如果系統(tǒng)切到了其他的mode,比如說滑動一個scrollView,那么timer會等待,直到系統(tǒng)回到NSDefaultRunLoopMode模式下面。如果你的本意是不管怎么樣,N秒后觸發(fā)timer,那么必須要修改timer執(zhí)行的mode。
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
否則,觸發(fā)時間會在停止滑動scrollView后的某一個時間,中間的偏差就看你滑了多久的scrollView。
另外需要注意的地方是,一個線程如果沒有開啟Runloop, NSTimer會不生效。
dispatch_after
dispatch_after就好多了,不依賴于Runloop,但是沒法取消。建議不需要取消的時候,都使用dispatch_after。
GCD Dispatch Source Timer
是用GCD timer也是可以的,但是有個問題就是首次觸發(fā)時間貌似沒法直接控制,dispatch_resume之后就立即執(zhí)行了第一次。
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW,5 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
[self showAlertView];
});
dispatch_resume(self.timer);
注意持有dispatch_source_t對象。