在 iOS 开发中,使用 NSTimer 时,经常会遇到循环引用的问题。以下是几种解决方案:

  1. 使用 weak 引用:在 NSTimer 的回调方法中,使用 weak 引用来引用 self,防止循环引用。示例代码如下:
__weak typeof(self) weakSelf = self;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:weakSelf selector:@selector(timerFired:) userInfo:nil repeats:YES];
  1. 使用 block:将 NSTimer 的回调方法包装成 block,然后在 block 内部使用 weak 引用来引用 self。示例代码如下:
__weak typeof(self) weakSelf = self;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 block:^{ 
    [weakSelf timerFired:timer];
} repeats:YES];
  1. 使用 GCD 的定时器:使用 dispatch_source_t 创建一个 GCD 的定时器,然后在 block 内部使用 weak 引用来引用 self。示例代码如下:
__weak typeof(self) weakSelf = self;
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{ 
    [weakSelf timerFired];
});
dispatch_resume(timer);
  1. 使用 CADisplayLink:CADisplayLink 是一个和屏幕刷新频率相同的定时器,可以用来实现每帧都执行的操作。在 CADisplayLink 的回调方法中,使用 weak 引用来引用 self。示例代码如下:
__weak typeof(self) weakSelf = self;
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:weakSelf selector:@selector(timerFired:)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

无论使用哪种方法,都需要注意在适当的时候停止或者销毁 NSTimer,以避免内存泄漏。


原文地址: https://www.cveoy.top/t/topic/hWIF 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录