倒计时是电商APP中经常遇到的,倒计时的技术实现,Apple的Foundation框架提供了NSTimer类
倒计时的实现如下:
HZTimer.h
@protocol HZTimerDelegate <NSObject>
- (void)timerHandleEventWithLeftSeconds:(NSInteger)seconds;
@end
@interface HZTimer : NSObject
@property (nonatomic, weak) id <HZTimerDelegate> delegate;
- (void)stop;
- (void)start;
@end
.m
#import "HZTimer.h"
@interface HZTimer ()
{
NSTimer *timer;
NSInteger seconds;
}
@end
@implementation HZTimer
- (instancetype)init{
self = [super init];
return self;
}
- (void)stop{
[timer invalidate];
timer = nil;
}
- (void)start{
seconds = 5;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFired) userInfo:nil repeats:YES];
}
- (void)timerFired{
seconds--;
if (seconds >= 0) {
if (self.delegate && [self.delegate respondsToSelector:@selector(timerHandleEventWithLeftSeconds:)]) {
[self.delegate timerHandleEventWithLeftSeconds:seconds];
}
}
}
- (void)dealloc{
NSLog(@"---------------timer-dealloc");
}
@end
外界的使用:
#import "ViewController.h"
#import "HZTimer.h"
@interface ViewController ()<HZTimerDelegate>
@property (strong, nonatomic) IBOutlet UILabel *titleLabel;
@end
@implementation ViewController
- (IBAction)startBtnClick:(UIButton *)sender {
[self fireTimer];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)fireTimer{
HZTimer *timer = [[HZTimer alloc] init];
timer.delegate = self;
[timer start];
}
- (void)timerHandleEventWithLeftSeconds:(NSInteger)seconds{
self.titleLabel.text = [NSString stringWithFormat:@"%02zd",seconds];
}
创建timer时,需要绑定target对象self,所以timer强引用实例self,而timer又是作为实例变量或者属性被实例self所引用所以这样就形成了一个引用环
self => timer => self
导致内存泄漏
修改后如下:
.m
#import "HZTimer.h"
@interface HZTimer ()
{
NSTimer *timer;
NSInteger seconds;
}
@end
@implementation HZTimer
- (instancetype)init{
self = [super init];
return self;
}
- (void)stop{
[timer invalidate];
timer = nil;
}
- (void)start{
seconds = 5;
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerFired) userInfo:nil repeats:YES];
}
- (void)timerFired{
seconds--;
if (seconds >= 0) {
if (self.delegate && [self.delegate respondsToSelector:@selector(timerHandleEventWithLeftSeconds:)]) {
[self.delegate timerHandleEventWithLeftSeconds:seconds];
}
}else{
[self stop];
}
}
- (void)dealloc{
NSLog(@"---------------timer-dealloc");
}
@end
这样HZTimer类的dealloc就被释放掉了