iOS 高级开发之内存管理之定时器

定时器内存管理 3 种方案 DEMO
CADisplayLink、NSTimer使用注意
CADisplayLink、NSTimer会对target产生强引用,target又对它们产生强引用,那么就会引发循环引用

先看一段示例代码

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
//    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(start)];
//    [self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    __weak typeof(self) weakSelf = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:weakSelf selector:@selector(start) userInfo:nil repeats:YES];
    
}

//开始
-(void)start {
    NSLog(@"%s",__func__);
}

-(void)dealloc {
    [self.timer invalidate];
}

timer 和 self 进行了相互引用.导致不能释放. 那么 传入一个 weak 修饰的 self 进去可以解决吗? 答案是不能的!

猜测 timer 内部有一个strong 属性 对传进来的 target 进行强引用.所以导致不能释放

解决方案: 之所以会导致内存不释放, 是因为循环引用导致的. 我们无法改变 NSTimer 里面的属性. 那么我们加入一个"第三者",来打破循环引用


image.png

主要代码:

#import "TimerPersent.h"

@implementation TimerPersent
+(instancetype)initWithObject:(NSObject *)obj {
    TimerPersent *persent = [[TimerPersent alloc] init];
    persent.target = obj;
    return  persent;
}
//消息转发. 让传进来的 target去响应
- (id)forwardingTargetForSelector:(SEL)aSelector {
    return  self.target;
}
@end

NSTimer 的创建

  self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:[TimerPersent initWithObject:self] selector:@selector(start) userInfo:nil repeats:YES];

完美解决.

定时器采用使用 block,传入 weakSelf 可以解决循环引用

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
//    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(start)];
//    [self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    __weak typeof(self) weakSelf = self;
//    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:weakSelf selector:@selector(start) userInfo:nil repeats:YES];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:true block:^(NSTimer * _Nonnull timer) {
        [weakSelf start];
    }];
    
}

//开始
-(void)start {
    NSLog(@"%s",__func__);
}

-(void)dealloc {
    [self.timer invalidate];
    NSLog(@"销毁了");
}

你可能感兴趣的:(iOS 高级开发之内存管理之定时器)