变更记录
方案名称
NSTimer - 解决 NSTimer 的循环引用问题导致的内存泄漏
关键字
NSTimer \ 循环引用 \ Retain Cycle \ 内存泄漏
需求场景
- 使用 NSTimer 造成对象无法释放,出现循环引用
参考链接
- Why’s Blog - iOS 中的 NSTimer(推荐)
详细内容
由于 NSTimer 中 target 对 self 对象的强引用,造成在 dealloc 方法中无法调用 invalidate;
不调用 invalidate 永远不会进入 dealloc 方法,而不进入 dealloc 方法则永远不会调用 invalidate;
为了解决这一问题,可以使用如下 category 中提供的方法初始化,避免了 NSTimer 中 target 对 self 对象的强引用,
这样就可以在 dealloc 方法中正常调用 invalidate 了
NSTimer+Weak.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #import <Foundation/Foundation.h>
@interface NSTimer (Weak)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats;
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats;
@end
|
NSTimer+Weak.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #import "NSTimer+Weak.h"
@implementation NSTimer (Weak)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats { return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(timerUpdateWithBlock:) userInfo:[block copy] repeats:repeats]; }
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats { return [self timerWithTimeInterval:interval target:self selector:@selector(timerUpdateWithBlock:) userInfo:[block copy] repeats:repeats]; }
+ (void)timerUpdateWithBlock:(NSTimer*)timer{ void (^timerBlock)() = timer.userInfo; if(timerBlock){ timerBlock(); } }
@end
|
效果图
(无)
备注
(无)