zoukankan      html  css  js  c++  java
  • OC原理解决定时器的循环引用

    对于以下代码:

    @property (strong, nonatomic) NSTimer *timer;
    
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];
    
    - (void)timerTest
    {
        NSLog(@"%s", __func__);
    }
    
    - (void)dealloc
    {
        [self.timer invalidate];
    }

    运行代码之后,发现当前对象并没有销毁,定时器并没有销毁,其实是由于当前对象对timer进行强引用,而timer中的target又对当前对象进行强应用,导致循环引用

    解决这种循环引用的有两种,一个timer创建的时候用block代码如下,并声明weakSelf属性,代码如下:

    __weak typeof(self) weakSelf = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
            [weakSelf timerTest];
    }];

    第二种创建一个中间对象,里面声明一个weak的target的对象,再利用runtime的转发机制,有target去执行

    创建LBTemp的类,代码如下:

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface LBTemp : NSObject
    + (instancetype)tempWithTarget:(id)target;
    @property (weak, nonatomic) id target;
    @end
    
    #import "LBTemp.h"
    
    @implementation LBTemp
    + (instancetype)tempWithTarget:(id)target
    {
        LBTemp *temp = [[LBTemp alloc] init];
        temp.target = target;
        return temp;
    }
    
    - (id)forwardingTargetForSelector:(SEL)aSelector
    {
        return self.target;
    }
    @end

    创建timer代码如下:

    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[LBTemp tempWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];

    同样的CADisplayLink循环引用问题也可以用第二种方法解决

  • 相关阅读:
    【转】使用Javascript改变HTML内容 拓荒者
    【转】ASP.NET MVC 过滤器Filter 拓荒者
    【转】JavaScript简介 拓荒者
    edge.js架起node.js和.net互操作桥梁
    利用Node.js为Node.js生成HttpStatusCode辅助类并发布到npm
    nodejs上HTML分析利器nodejquery
    JavaScript 函数replace揭秘
    利用Node.js本地构建
    Angularjs的IOC Inject分析
    团队文化中的害群之马
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/14449413.html
Copyright © 2011-2022 走看看