iOS三种定时器:NSTimer,CADisplayLink,dispatch_source_t

本文深入解析iOS中的三种定时器:NSTimer、CADisplayLink和dispatch_source_t。详细介绍了它们的工作原理、优缺点及使用场景。NSTimer适用于简单定时任务,但计时不够精确;CADisplayLink基于屏幕刷新率,提供更精准的定时;dispatch_source_t则提供了高精度定时,但需独立队列处理。
摘要由CSDN通过智能技术生成

iOS三种定时器

一、 NSTimer

注意点:timerWithTimeInterval: target: selector: userInfo: repeats:凡是timerWithTimeInterval开头的都是需要手动添加到RunLoop中。scheduledTimerWithTimeInterval开头的方法内部自动添加到RunLoop中。

//这里的self换成weakSelf 也不行,里面找到target的地址再强引用
NSTimer * timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(test) userInfo:nil repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

如果添加到子线程中:

  1. 保证RunLoop创建并且Run起来了

  2. timer需要添加到RunLoop中[loop addTimer:timer forMode:NSRunLoopCommonModes];

优点: 方便使用
缺点: 计时不精确,容易造成循环引用

设置的TimeInterval是最小时间间隔

不管是一次性的还是周期性的timer的实际触发事件的时间,都会与所加入的RunLoop和RunLoop Mode有关,如果此RunLoop正在执行一个耗时操作,timer就会被延时出发。重复性的timer遇到这种情况,如果延迟超过了一个周期,则会在延时结束后立刻执行,并按照之前指定的周期继续执行。

RunLoop强引用Timer,timer在强引用target,解决强引用:

  1. 利用NSProxy,消息转发
  2. 使用新的的API:timerWithTimeInterval: repeats: block:(只对iOS10 以后)
二、CADisplayLink

CADisplayLink:根据刷新频率来计算时间间隔

CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(test)];
[link setPreferredFramesPerSecond:20];
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

注意:

  • setPreferredFramesPerSecond表示每秒执行的次数;
  • 必须添加到RunLoop

优点: 只要设备屏幕刷新频率保持在60fps,那么其触发时间上是最准确的。
缺点: 由于依托于屏幕刷新频率,如果CPU任务过重,那么会影响屏幕刷新,触发事件也会受到相应影响。

三、dispatch_source_t

注意:dispatch_source_t _timer;全局的,不然创建完了执行一次就销毁了

dispatch_source_t _timer;
void testGCDSourceTimer() {
    dispatch_queue_t queue = dispatch_queue_create("com.ob", DISPATCH_QUEUE_CONCURRENT);
    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(_timer, ^{
        NSLog(@"test---");
    });
    dispatch_resume(_timer);
}

//开始
dispatch_resume(_timer);
//暂停
dispatch_suspend(_timer);
//销毁
dispatch_source_cancel(_timer);

优点: 非常精确,要想达到百分比精确需要单独拥有一个队列,只处理time相关的任务,并且time的回调处理时长不能操过设置的时间间隔。

缺点: 不受RunLoop的影响,需要注意内存管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值