使用NSTimer的时候可能存储内存泄漏问题,例如:当控制器销毁时,会发现dealloc没有被调用,问题的原因在于timer对控制器对象有强引用,即使是使用了weakSelf
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
__weak typeof(self) weakSelf = self;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:weakSelf selector:@selector(timerInvoke:) userInfo:nil repeats:YES];
self.timer = timer;
self.timer = timer;
}
- (void)timerInvoke:(NSTimer *)timer{
NSLog(@"%s",__func__);
}
- (void)dealloc{
[self.timer invalidate];
NSLog(@"%s",__func__);
}
@end
如需解决这个问题,就得解决问题的原因timer对target对象的强引用,方式可以修改timer的引用为间接对象target,通过间接对象传递真实监听对象和方法,那么当真实对象的dealloc销毁时,调用[self.timer invalidate]; 那么对象既可以销毁,timer也可以销毁,timer销毁了,间接对象target也就可以销毁.
#import "ViewController.h"
#import "HJTimerTarget.h"
@interface ViewController ()
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// __weak typeof(self) weakSelf = self;
// NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:weakSelf selector:@selector(timerInvoke:) userInfo:nil repeats:YES];
// self.timer = timer;
NSTimer *timer = [HJTimerTarget scheduledTimerWithTimeInterval:2 target:self selector:@selector(timerInvoke:) userInfo:nil repeats:YES];
self.timer = timer;
}
- (void)timerInvoke:(NSTimer *)timer{
NSLog(@"%s",__func__);
}
- (void)dealloc{
[self.timer invalidate];
NSLog(@"%s",__func__);
}
@end
#import <Foundation/Foundation.h>
@interface HWWeakTimerTarget : NSObject
@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL selector;
@property (nonatomic, weak) NSTimer* timer;
+ (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
target:(id)aTarget
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats;
@end
#import "HWWeakTimerTarget.h"
@implementation HWWeakTimerTarget
+ (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
target:(id)aTarget
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats {
HWWeakTimerTarget* timerTarget = [[HWWeakTimerTarget alloc] init];
timerTarget.target = aTarget;
timerTarget.selector = aSelector;
timerTarget.timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:timerTarget
selector:@selector(fire:)
userInfo:userInfo
repeats:repeats];
return timerTarget.timer;
}
- (void) fire:(NSTimer *)timer {
if(self.target) {
[self.target performSelector:self.selector withObject:timer.userInfo];
} else {
[self.timer invalidate];
}
}
- (void)dealloc{
NSLog(@"%s",__func__);
}
@end
运行结果:
-[ViewController timerInvoke:] -[ViewController timerInvoke:] -[ViewController timerInvoke:] -[ViewController timerInvoke:] -[HJTimerTarget dealloc] -[ViewController dealloc]
浙公网安备 33010602011771号