📜  timer displayLink (1)

📅  最后修改于: 2023-12-03 15:05:35.738000             🧑  作者: Mango

Timer 和 displayLink

在 iOS 开发中,我们经常需要用到定时器(Timer)来执行一些定时任务或者周期性任务,包括播放音乐、动画效果、轮询等。在定时器的实现方面,除了使用 NSTimer 之外,还有一种更为灵活且性能更好的方案,即 Core Animation 提供的 displayLink

Timer

NSTimer 是 Foundation 框架中用于定时器的类,我们可以使用该类来在主线程中创建一个计时器,并在指定时间间隔后执行相应的任务。

创建 NSTimer 对象的方式有很多种,其中一种常用的方式是使用计时器的方法:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval target:(id)target selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)repeats;

其中,interval 表示计时器触发的时间间隔;target 表示计时器执行任务的对象;aSelector 表示计时器触发时调用的方法;userInfo 表示计时器执行中的用户数据;repeats 表示计时器是否重复执行。

使用 NSTimer 的示例代码如下:

- (void)startTimer {
    // 创建一个计时器
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                  target:self
                                                selector:@selector(handleTimer:)
                                                userInfo:nil
                                                 repeats:YES];
}

- (void)stopTimer {
    // 停止计时器
    [self.timer invalidate];
    self.timer = nil;
}

- (void)handleTimer:(NSTimer *)timer {
    // 计时器任务
}

需要注意的是,NSTimer 创建的计时器必须加入到运行循环中才能正常工作,否则就会失效。而且,如果定时器触发时间被其他任务阻碍或者线程阻塞的话,计时器任务就不能按时执行,会导致计时器失效。

displayLink

displayLink 是 Core Animation 用于性能提升的类,它与 NSTimer 类似,都可以用来定时器,但 displayLink 的精确度更高,它能够做到每秒钟调用 60 次。

displayLink 是一个 CADisplayLink 对象,它以特定帧率(默认是每秒 60 帧)定期刷帧,并调用绑定的 selector 方法。它的使用非常简单:只要实现一个方法来处理每一帧的处理,再将这个方法与 displayLink 相绑定,然后启动 displayLink 即可。

使用 displayLink 的示例代码如下:

- (void)startDisplayLink {
    // 创建一个 CADisplayLink 对象
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    // 将 CADisplayLink 对象加入到运行循环中
    [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)stopDisplayLink {
    // 停止 CADisplayLink 与运行循环的绑定
    [self.displayLink invalidate];
    self.displayLink = nil;
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink {
    // 每一帧的处理
}

需要注意的是,displayLink 不能够像 NSTimer 一样控制任务的间隔时间,而是以常数 1/60 秒的间隔调用 selector 方法。因此,如果需要控制任务的时间间隔,需要手动计算时间,并在 selector 方法中控制任务的执行。

此外,displayLink 一般用于视图动画的实现,能够提高视图动画的帧数和流畅度。对于其他定时器的实现,建议先使用 NSTimer,如果发现定时器执行有阻塞情况或者精度不够的情况,再考虑使用 displayLink