常用的延时调用

  • iOS中的几种常用定时器,是否严格按照设定的时间间隔按时执行,支持的最小时间间隔

NSTimer

  • 可以精确到50-100毫秒. 能满足对间隔要求不严格、对精确度不敏感的需求

    • NSTimer理论上最小精度为 0.1 毫秒。不过由于受 Runloop 的影响,会有 50 ~ 100 毫秒的误差,所以,实际精度可以认为是 0.1 秒。

    • 不可靠,NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了.timer其所在的RunLoop会定时检测是否可以触发NSTimer的事件.但由于iOS有多个RunLoop的运行模式,如果被切到另一个runloop, NSTimer就不会被触发.每个RunLoop的循环间隔也无法保证,当某个任务耗时比较久,RunLoop的下一个消息处理就只能顺延,导致NSTimer的时间已经到达,但Runloop却无法及时触发 NSTimer,导致该时间点的回调被错过。

  • 创建方法:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(id)ui repeats:(BOOL)rep;
  • 除了参数区别之外.这五种初始化方法的不同之处在于:

    • timerWith这两个类方法以及init方法,只是创建了定时器,必须手动加入到当前runloop中去.如果不手动加入主循环池中,将不会循环执行。并且如果不手动调用fire,则定时器不会启动。

    • scheduled这两个类方法是创建一个定时器,并加入到当前运行循环中.不需要手动调用fire,会自动执行。

  • 使用 [timer fire];可以触发定时器.

    • fire并不是启动一个定时器,只是提前触发而已.

    • 在重复执行(repeat = YES)的定时器中调用此方法后立即触发该定时器,但不会中断其之前的执行计划;

    • 在不重复执行(repeat = NO)的定时器中调用此方法,立即触发后,就会使这个定时器失效。

  • 销毁定时器,使用 [timer invalidate]; 这是唯一将定时器从循环池中移除的方法.

NSObject的 performSelector

  • NSObject对NSTimer封装后提供的一个比较简单的延时方法.当调用NSObject的performSelecter:afterDelay:后,实际上其内部会创建一个Timer并添加到当前线程的RunLoop中.所以这种方法的精确度和可靠性同timer.

  • 使用方法

  • cancle方法

GCD

  • 最小精度为纳秒,误差在50毫秒以内.

  • 比较常用的 dispatch_after方法并没有直接的cancel方法

  • 更加精确的定时器 消耗性能

  • 取消方法

# 这些是比较常用的,一般使用场景下的也足够了,如果需要更精确的,系统有给提供误差更小的高精度定时器

Last updated