常见iOS中定时执行代码的方式

157 阅读3分钟

在iOS开发中,有多种方式用于定时执行代码,选择合适的方式取决于具体的需求和场景,综合考虑时间精度、线程安全性、用途和安全性等因素。以下是一些常见的定时执行代码的方式:

NSTimer

  • 时间精度: 相对较低,通常以毫秒级别的时间间隔执行。
  • 线程安全: 在多线程环境中,需要小心谨慎地使用,确保在主线程中更新UI。对于定时器的启动和停止,最好在主线程中执行。
  • 用途: 适用于相对较慢的定时任务,例如周期性地执行一些后台任务、更新 UI 等。不适用于需要高精度、与屏幕刷新同步的任务。
  • 安全性: 需要小心处理循环引用的问题,确保在需要的时候手动停止定时器以防止内存泄漏。在多线程环境中使用时需要考虑线程安全性。
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                  target:self
                                                selector:@selector(timerFired:)
                                                userInfo:nil
                                                 repeats:YES];
    

CADisplayLink

  • 时间精度: 相对较高,以屏幕刷新率(通常60帧/秒)为基准,用于与屏幕同步的动画。
  • 线程安全: 在主线程中运行,与 UI 更新同步,无需过多关心线程安全性。
  • 用途: 适用于需要与屏幕刷新同步的任务,例如实现动画、游戏循环等。
  • 安全性: 由于与屏幕同步的特性,不容易出现循环引用问题。在对象被释放时,CADisplayLink 会自动停止。
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkFired:)];
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    

GCD 定时器:

  • 时间精度: 可以达到较高的时间精度。
  • 线程安全: GCD 定时器通常是线程安全的,因为它们运行在 GCD 的队列中,可以方便地指定队列。
  • 用途: 适用于相对简单的定时任务,具有较好的性能。可以根据需求灵活地调整定时器的执行队列。
  • 安全性: GCD 定时器相对较为安全,但仍需小心处理循环引用的问题。
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), 1.0 * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(timer, ^{
    // 定时执行的代码
    });
    dispatch_resume(timer);
    

performSelector

  • 时间精度: 由于其依赖于 NSRunLoop,时间精度相对较低。
  • 线程安全: 在主线程中执行,需要注意在多线程环境中的使用。
  • 用途: 适用于简单的延时执行任务,例如延时加载、简单的动画等。
  • 安全性: 需要小心处理循环引用问题,并注意在取消定时任务时的情况。
    [self performSelector:@selector(delayedTask) withObject:nil afterDelay:2.0];
    

注意事项:

  1. 循环引用: 在使用 NSTimerperformSelector 时,需要小心处理循环引用问题,避免导致内存泄漏。
  2. 线程安全: 在多线程环境中,需要谨慎使用 NSTimerperformSelector,确保在主线程中更新 UI。
  3. 定时器停止: 在适当的时机停止定时器,避免不必要的定时器继续运行,导致资源浪费和潜在的问题。
  4. GCD 定时器的队列选择: 在使用 GCD 定时器时,根据任务的性质选择合适的队列,以确保线程安全性。
  5. UI 更新: 如果定时任务涉及到 UI 更新,最好在主线程中执行,以避免界面操作的不确定性。

选择合适的定时执行方式取决于具体的需求和场景,综合考虑时间精度、线程安全性、用途和安全性等因素。