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