• 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方法中。具体可以自己试试。

  • 相关阅读:
    Linux查看物理CPU个数、核数、逻辑CPU个数
    shell脚本中格式化日期
    MySQL中常用字符串函数
    Xtrabackup 使用方法
    LinuxShell算术运算
    mysql高可用方案MHA介绍
    CentOS安装scp命令
    源码编译安装MySQL
    mysql编译参数详解(./configure)
    SparkStreaming 结合Kafka 时丢数据
  • 原文地址:https://www.cnblogs.com/lingtingvfengsheng/p/4846764.html
Copyright © 2020-2023  润新知