美文网首页
NSTimer/CADisplayLink循环引用

NSTimer/CADisplayLink循环引用

作者: 五蕴盛 | 来源:发表于2021-11-16 14:05 被阅读0次

    我只是想记录一下,设置不了文章仅自己可见!!!shit!

    1.NSTimer/CAD 实现分类 使用block打破引用

    1.1 在分类里面实现

    在初始化timer/cadlink对象的时候,指定target的时候,会保留其目标对象,其实就是这个target。在分类中,定时器对象指定的target是timer/cadlink的类对象,这是个单例对象,因此计时器的是否保留他无所谓,因为类对象无需回收。

    2. YYWeakProxy等

    NSproxy本身是一个抽象类,他遵循NSObject协议,提供了消息转发的接口。NSProxy通常来实现消息转发和懒加载初始化资源。但,需要创建NSProxy的子类,实现init以及消息转发的相关方法,才可以用。
    YYWeakProxy继承了NSProxy,定义了一个弱引用的target对象,重写消息转发,让target对象去处理接收到的消息,等于让原来ViewController对象去直接处理但这里拐了一个弯,在这个弯里用弱引用解除了timer和controller的本来的强引用。

    引用链 以下用——代表强引用 ,用---代表弱应用

    Controller——>NSTime/CADisplayLink——>YYWeakProxy--->Controller

    代码

    //  NSTimer+QSTool.h
    typedef void(^QSExecuteTimerBlock) (NSTimer *timer);
    
    @interface NSTimer (QSTool)
    
    + (NSTimer *)qs_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval executeBlock:(QSExecuteTimerBlock)block repeats:(BOOL)repeats;
    
    @end
    
    //  NSTimer+QSTool.m
    @implementation NSTimer (QSTool)
    
    + (NSTimer *)qs_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval executeBlock:(QSExecuteTimerBlock)block repeats:(BOOL)repeats{
    
        NSTimer *timer = [self scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(qs_executeTimer:) userInfo:[block copy] repeats:repeats];
        return timer;
    }
    
    + (void)qs_executeTimer:(NSTimer *)timer{
    
        QSExecuteTimerBlock block = timer.userInfo;
        if (block) {
            block(timer);
        }
    }
    
    @end
    
    
    //  CADisplayLink+QSTool.h
    @class CADisplayLink;
    
    typedef void(^QSExecuteDisplayLinkBlock) (CADisplayLink *displayLink);
    
    @interface CADisplayLink (QSTool)
    
    @property (nonatomic,copy)QSExecuteDisplayLinkBlock executeBlock;
    
    + (CADisplayLink *)displayLinkWithExecuteBlock:(QSExecuteDisplayLinkBlock)block;
    
    @end
    
    //  CADisplayLink+QSTool.m
    @implementation CADisplayLink (QSTool)
    
    - (void)setExecuteBlock:(QSExecuteDisplayLinkBlock)executeBlock{
    
        objc_setAssociatedObject(self, @selector(executeBlock), [executeBlock copy], OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (QSExecuteDisplayLinkBlock)executeBlock{
    
        return objc_getAssociatedObject(self, @selector(executeBlock));
    }
    
    + (CADisplayLink *)displayLinkWithExecuteBlock:(QSExecuteDisplayLinkBlock)block{
    
        CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(qs_executeDisplayLink:)];
        displayLink.executeBlock = [block copy];
        return displayLink;
    }
    
    + (void)qs_executeDisplayLink:(CADisplayLink *)displayLink{
    
        if (displayLink.executeBlock) {
            displayLink.executeBlock(displayLink);
        }
    }
    @end
    
    

    1.使用category分类

    - (void)viewDidLoad {
       [super viewDidLoad];
      // ...
       __weak typeof(self) weakSelf = self;
       self.timer = [NSTimer qs_scheduledTimerWithTimeInterval:timeInterval executeBlock:^(NSTimer *timer) {
           __weak typeof(weakSelf) strongSelf = weakSelf;
           [strongSelf executeTimer:timer];
       } repeats:YES];
       [self.timer fire];
       //...
    }
    
    - (void)executeTimer:(NSTimer *)timer{
       //do something
    }
    
    - (void)dealloc{
     [self.timer invalidate];
    }
    
    

    2.使用yyweakproxy

    - (void)viewDidLoad {
        [super viewDidLoad];
       // ...
        self.displayLink = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(executeDispalyLink:)];
        [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
       //...
    }
    
    - (void)executeDispalyLink:(CADisplayLink *)displayLink{
        //...
    }
    
    - (void)dealloc{
          [self.displayLink invalidate];
    }
    
    

    相关文章

      网友评论

          本文标题:NSTimer/CADisplayLink循环引用

          本文链接:https://www.haomeiwen.com/subject/kmfhtrtx.html