Timer 强引用无法释放问题

问题描述:

当你使用Timer时,特别repeat时,你的Timer所在类往往无法调用dealloc,也就该类一直有strong reference指向它(使它无法被释放,造成内存泄露)。


问题原理探究:

当你schedule你的timer到runloop时,runloop会对timer持有强引用。而Timer会对它的target或都invocation持有强引用。
runloop --->(strong) timer ---->(strong) target or invocation
在你的timer invalidate之前你的target会一直无法被释放,不管你的target 对timer是持有强引用还是弱引用。强引用的话就是strong reference circle。


解决方案

  1. 你能确保一定会把你的timer invalidate掉。
  2. 如果你无法确保一定会invalidate你的tiemr。就需要引入第三个类,来打破强引用:
 @interface MyClassTimerDeliver : NSObject

@property (nonatomic, weak) id delegate;
- (void)renderExpiredCountdown:(id)sender;

@end

@implementation MyClassTimerDeliver

- (void)renderExpiredCountdown:(id)sender {
    if([self.delegaterespondsToSelector:@selector(renderExpiredCountdown:)]) {
        [self.delegateperformSelector:@selector(renderExpiredCountdown:) withObject:nil];
    }
}
@end

@interface MyClass : SomeSuperClass {
    NSTimer *_timer;
}

@property (nonatomic, strong) MyClassTimerDeliver *timerDeliver;

@end

@implementation MyClass

- (void)dealloc {
    if (_timer) {
        [_timerinvalidate];
        _timer = nil;
        
    }
}

- (void)doTimer {
    // code here actually do the tiemr
}

- (void)renderExpiredCountdown:(id)sender {
    [_timeDeliver.delegatedoTimer];
}

- (void)createTimer {
    _timeDeliver = [[MDMyLotteryDataSourceTimerDeliveralloc] init];
    _timeDeliver.delegate = self;
    //只创建一个定时器NSTimer
    if (!_timer) {
        _timer = [NSTimerscheduledTimerWithTimeInterval:1.0target:_timeDeliverselector:@selector(renderExpiredCountdown:) userInfo:nilrepeats:YES];
        [[NSRunLoopcurrentRunLoop] addTimer:_timerforMode:NSRunLoopCommonModes];//解决滚动的时候计时器就会停止
    }
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 引言 定时器:A timer waits until a certain time interval has el...
    时间已静止阅读 2,862评论 6 34
  • 定时器: 需要被添加到Runloop,否则不会运行,当然添加的Runloop不存在也不会运行 还要指定添加到的Ru...
    Sunli_阅读 1,742评论 0 3
  • # 前言 反复地复习iOS基础知识和原理,打磨知识体系是非常重要的,本篇就是重新温习iOS的内存管理。 内存管理是...
    Vein_阅读 828评论 0 2
  • 今年的夏天异常的热,似乎和心情也有很大关系。 除了上班,每天要拖地洗衣,收拾生活垃圾,按耐着焦躁的心情做晚饭(幸亏...
    烈酒长歌阅读 332评论 0 1
  • 请别误会,这不是一部法律,它只是有关孩子教育的方法。 有孩子的家长们在一起,多半会吐槽自家孩子种种的不是;有小孩的...
    妮妮菜阅读 505评论 0 0