码迷,mamicode.com
首页 > 移动开发 > 详细

iOS 里面 NSTimer 防止 循环引用

时间:2015-09-29 18:23:21      阅读:308      评论:0      收藏:0      [点我收藏+]

标签:

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

iOS 里面 NSTimer 防止 循环引用

标签:

原文地址:http://www.cnblogs.com/lingtingvfengsheng/p/4846764.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!