美文网首页
NSTimer中的循环引用

NSTimer中的循环引用

作者: xxxxxxxxx_ios | 来源:发表于2018-12-26 13:48 被阅读3次
    • 循环引用代码
    #import "ViewController.h"
    
    @interface ViewController ()
    @property (nonatomic, strong) NSTimer *timer;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];
    }
    
    - (void)timerTest {
        
        NSLog(@"%s",__func__);
    }
    
    - (void)dealloc {
        
        NSLog(@"%s",__func__);
        [self.timer invalidate];
    }
    
    @end
    
    • 说明
      上述代码中,ViewController强引用Timer,Timer中target为ViewController,会对控制器有一个强引用,产生循环引用。
    • 解决方案
      1.更换NSTimer初始化方法,使用block方式,__weak修饰target.
    #import "ViewController.h"
    
    @interface ViewController ()
    @property (nonatomic, strong) NSTimer *timer;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    //    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];
        
        __weak typeof(self) weakSelf = self;
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
            [weakSelf timerTest];
        }];
    }
    
    - (void)timerTest {
        
        NSLog(@"%s",__func__);
    }
    
    - (void)dealloc {
        
        NSLog(@"%s",__func__);
        [self.timer invalidate];
    }
    
    @end
    

    2.使用NSPorxy,中间弱引用对象,打破循环。
    创建一个类继承自NSProxy.

    .h文件

    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface YMProxy : NSProxy
    /** target */
    @property (nonatomic, weak) id target;
    + (id)proxyWithTarget:(id)target;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    

    .m文件

    #import "YMProxy.h"
    
    @implementation YMProxy
    
    + (id)proxyWithTarget:(id)target {
        
        /// 初始化代理对象
        YMProxy *proxy = [YMProxy alloc];
        proxy.target = target;
        return proxy;
    }
    
    // 消息转发阶段会调用的方法 当proxy对象找不到控制器中的方法时,会调用这个方法,进行方法签名
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
        
        return [self.target methodSignatureForSelector:sel];
    }
    
    // 方法签名返回值有值的时候,调用此方法 进行消息转发
    - (void)forwardInvocation:(NSInvocation *)invocation {
        
        [invocation invokeWithTarget:self.target];
    }
    
    @end
    

    ViewController.m

    #import "ViewController.h"
    #import "YMProxy.h"
    @interface ViewController ()
    @property (nonatomic, strong) NSTimer *timer;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[YMProxy proxyWithTarget:self] selector:@selector(timerTest) userInfo:nil repeats:YES];
        
    }
    
    - (void)timerTest {
        
        NSLog(@"%s",__func__);
    }
    
    - (void)dealloc {
        
        NSLog(@"%s",__func__);
        [self.timer invalidate];
    }
    
    @end
    
    

    以上就是NSTimer循环应用解决方案。

    相关文章

      网友评论

          本文标题:NSTimer中的循环引用

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