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