zoukankan      html  css  js  c++  java
  • iOS 里面 NSTimer 防止 循环引用

    使用NSTimer的类

    #import "TBTimerTestObject.h"
    #import "TBWeakTimerTarget.h"
    
    @interface TBTimerTestObject()
    
    @property (nonatomic, weak) NSTimer *timer;
    
    @end
    
    @implementation TBTimerTestObject
    
    - (void)dealloc
    {
        NSLog(@"timer is dealloc");
    }
    
    - (id)init
    {
        self  = [super init];
        
        if (self) {
            TBWeakTimerTarget *timerTarget =[[TBWeakTimerTarget alloc] initWithTarget:self andSelector:@selector(timerDidFire:)];
            
            _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:timerTarget selector:@selector(timerDidFire:) userInfo:nil repeats:YES];
        }
        return self;
    }
    
    - (void)timerDidFire:(NSTimer*)timer
    {
        NSLog(@"%@", @"1111111");
    }
    
    @end

    target类:

    头文件:

    #import <Foundation/Foundation.h>
    
    @interface TBWeakTimerTarget : NSObject
    
    - (instancetype) initWithTarget: (id)target andSelector:(SEL) selector;
    - (void)timerDidFire:(NSTimer *)timer;
    
    @end

    m文件:

    #import "TBWeakTimerTarget.h"
    
    @implementation TBWeakTimerTarget
    {
        __weak id _target;
        SEL _selector;
    }
    
    - (instancetype) initWithTarget: (id) target andSelector: (SEL) selector
    {
        self = [super init];
        if (self) {
            _target = target;
            _selector = selector;
        }
        return self;
    }
    
    - (void) dealloc
    {
        NSLog(@"TBWeakTimerTarget dealloc");
    }
    
    - (void)timerDidFire:(NSTimer *)timer
    {
        if(_target)
        {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [_target performSelector:_selector withObject:timer];
    #pragma clang diagnostic pop
        }
        else
        {
            [timer invalidate];
        }
    }
    @end

    使用示范:

    @interface ViewController ()
    
    @property (nonatomic, strong) TBTimerTestObject *obj;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (IBAction)tap:(id)sender
    {
        NSLog(@"tappp");
        
        self.obj = [[TBTimerTestObject alloc] init];
    
        [self performSelector:@selector(timerDidFired:) withObject:nil afterDelay:3];
    }
    
    - (void)timerDidFired:(NSTimer *)timer
    {
        self.obj = nil;
        NSLog(@"AppDelegate timerDidFired");
    }
    
    @end

    打印log:

    2015-09-29 16:58:40.120 XIBTest[21999:1136902] tappp
    2015-09-29 16:58:41.121 XIBTest[21999:1136902] 1111111
    2015-09-29 16:58:42.121 XIBTest[21999:1136902] 1111111
    2015-09-29 16:58:43.121 XIBTest[21999:1136902] 1111111
    2015-09-29 16:58:43.122 XIBTest[21999:1136902] timer is dealloc
    2015-09-29 16:58:43.122 XIBTest[21999:1136902] AppDelegate timerDidFired
    2015-09-29 16:58:44.121 XIBTest[21999:1136902] TBWeakTimerTarget dealloc

    具体参考了:

    http://stackoverflow.com/questions/16821736/weak-reference-to-nstimer-target-to-prevent-retain-cycle

    国内某些说在dealloc中写:

    timer.invalid;

    timer = nil;

    是不行的,因为循环引用了,都不会进入dealloc方法中。具体可以自己试试。

  • 相关阅读:
    数据结构——自学笔记一
    Xmind软件——xmind 8 pro下载激活推荐!!
    Java学习笔记之面向对象、static关键字
    解决“var/log/sysstat/sa21: 没有那个文件或目录 请检查是否允许数据收集”
    c++.net学习笔记
    Android Studio学习-连接真机测试教学
    Servlet总结二(文件路径)
    Servlet总结一
    多线程的使用
    Lock
  • 原文地址:https://www.cnblogs.com/lingtingvfengsheng/p/4846764.html
Copyright © 2011-2022 走看看