美文网首页
iOS NSTimer使用Proxy(伪基类)解决循环引用

iOS NSTimer使用Proxy(伪基类)解决循环引用

作者: 孜孜不倦_闲 | 来源:发表于2020-11-09 16:05 被阅读0次

    前语

    在开发中难免使用到NSTimer,为了避免循环引用,可能会在willDismiss来进行释放,置为nil;不过经过查阅大神资料,有更好的解决方法:NSProxy;
    下面来介绍一下

    实现

    先上代码:MyTimerProxy.h
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface MyTimerProxy : NSObject
    
    @property (nonatomic, weak) id target;
    + (instancetype)initWithTarget:(id)target;
    
    @end
    

    MyTimerProxy.m

    //
    //  MyTimerProxy.m
    //  Test-OC
    //
    //  Created by Old.Wang on 2020/11/9.
    //  Copyright © 2020 Old.Wang. All rights reserved.
    //
    
    #import "MyTimerProxy.h"
    
    @implementation MyTimerProxy
    
    + (instancetype)initWithTarget:(id)target{
        MyTimerProxy * proxy = [[MyTimerProxy alloc] init];
        proxy.target = target;
        return proxy;
    }
    
    - (void)forwardInvocation:(NSInvocation *)anInvocation{
        if ([self.target respondsToSelector:anInvocation.selector]) {
            [anInvocation invokeWithTarget:self.target];
        }
    }
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
        return [self.target methodSignatureForSelector:aSelector];
    }
    
    @end
    
    

    Controller层使用以及日志

    #import "ViewController.h"
    #import "MyTimerProxy.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) NSTimer  * t_timer;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        MyTimerProxy *myProxy = [MyTimerProxy initWithTarget:self];
        self.t_timer = [NSTimer timerWithTimeInterval:3 target:myProxy selector:@selector(runTimer) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.t_timer forMode:NSRunLoopCommonModes];
        
    }
    
    #pragma mark - timer
    - (void)runTimer{
        NSLog(@"Runing %s",__func__);
    }
    
    #pragma mark - Dealloc
    - (void)dealloc{
        [self.t_timer invalidate];
        self.t_timer = nil;
        
        NSLog(@"%s",__func__);
    }
    
    @end
    

    离开页面栈后,最后打印日志为:[viewController dealloc],对象释放;

    原理

    NSProxy解决循环引用原理图.png

    实际上通过弱化self - target 的强引用关系来解决引用环。

    相关文章

      网友评论

          本文标题:iOS NSTimer使用Proxy(伪基类)解决循环引用

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