使用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(@"%@", @"");
} @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:];
} - (void)timerDidFired:(NSTimer *)timer
{
self.obj = nil;
NSLog(@"AppDelegate timerDidFired");
} @end

打印log:

-- ::40.120 XIBTest[:] tappp
-- ::41.121 XIBTest[:]
-- ::42.121 XIBTest[:]
-- ::43.121 XIBTest[:]
-- ::43.122 XIBTest[:] timer is dealloc
-- ::43.122 XIBTest[:] AppDelegate timerDidFired
-- ::44.121 XIBTest[:] TBWeakTimerTarget dealloc

具体参考了:

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

国内某些说在dealloc中写:

timer.invalid;

timer = nil;

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

04-26 08:24