NSTimer作为一个经常使用的类,却有一个最大的弊病,就是会强引用target。造成调用timer很麻烦。稍有不慎就造成内存泄漏。
下面就是为解决问题做的封装。
直接上代码:
#import <Foundation/Foundation.h>
@interface LZLTimer :
NSObject
-(void)startTimerInterval:(NSTimeInterval)ti target:aTarget selector:(SEL)selector
userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
@end
#import "LZLTimer.h"
@interface LZLWeakTimerTarget :
NSObject
@property (nonatomic,weak)
id target;
@property (nonatomic,assign)
SEL selector;
- (void)timerDidFire:(NSTimer *)timer;
@end
@implementation LZLWeakTimerTarget
- (void)timerDidFire:(NSTimer *)timer {
if(_target) {
//消除arc警告
IMP imp = [_target
methodForSelector:_selector];
if ([NSStringFromSelector(_selector)
hasSuffix:@":"]) {
void (*func)(id,
SEL, id) = (void *)imp;
func(_target,
_selector, timer);
}else {
void (*func)(id,
SEL) = (void *)imp;
func(_target,
_selector);
}
} else {
[timer invalidate];
}
}
@end
@interface LZLTimer () {
NSTimer *_timer;
}
@end
@implementation LZLTimer
-(void)dealloc {
if (_timer!=nil) {
[_timer
invalidate];
_timer =
nil;
}
}
-(void)startTimerInterval:(NSTimeInterval)ti target:aTarget selector:(SEL)selector
userInfo:(id)userInfo repeats:(BOOL)yesOrNo {
if (nil ==
_timer) {
WMWeakTimerTarget *weakTarget = [[WMWeakTimerTarget
alloc] init];
weakTarget.target = aTarget;
weakTarget.selector = selector;
_timer = [NSTimer
scheduledTimerWithTimeInterval:ti
target:weakTarget selector:@selector(timerDidFire:)
userInfo:userInfo repeats:yesOrNo];
}
}
@end