系统提供的NSTimer类,很多的时候内存的释放是一个大问题,尤其是repeat方式的,通过调试发现它是基本上不释放的。我个人就考虑用GCD来实现一套定时器的功能。详细见下面的code:
//
// DispatchTimer.h
// WYJDemoSets
//
// Created by wuyj on 16/2/18.
// Copyright © 2016年 wuyj. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol DispatchTimerDelegate <NSObject>
- (void)dispatchTimerTask;
@end
typedef void (^DispatchTimerBlock)(void);
/*
采用GCD实现timer,这个实现不会出现timer不释放的问题;
*/
@interface DispatchTimer :NSObject
+ (DispatchTimer *)sharedDispatchTimer;
// 采用代理的方式,建议采用这种方式
- (void)createDispatchTimerInterval:(NSUInteger)interval delegate:(id <DispatchTimerDelegate>)delegate repeats:(BOOL)yesOrNo;
/* !!!!!! 采用block的方式,一定要注意block retain self的问题
类似这样使用:
__weak CycleScrollView *wself = self;
[[DispatchTimer sharedDispatchTimer] createDispatchTimerInterval:_interval block:^{
CycleScrollView *sself = wself;
[sself autoJumpPage];
} repeats:YES];
*/
- (void)createDispatchTimerInterval:(NSUInteger)interval block:(DispatchTimerBlock)timerBlock repeats:(BOOL)yesOrNo;
// 停止循环执行的timer
- (void)invalidate;
@end
//
// DispatchTimer.m
// WYJDemoSets
//
// Created by wuyj on 16/2/18.
// Copyright © 2016年 wuyj. All rights reserved.
//
#import "DispatchTimer.h"
@interface DispatchTimer ()
@property (nonatomic,strong) dispatch_source_t timer;
@property (nonatomic,weak) id<DispatchTimerDelegate> delegate;
@end
@implementation DispatchTimer
+ (DispatchTimer *)sharedDispatchTimer {
staticDispatchTimer *obj = nil;
staticdispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
obj = [[selfalloc] init];
});
return obj;
}
- (void)dealloc {
[selfinvalidate];
}
- (void)createDispatchTimerInterval:(NSUInteger)interval delegate:(id <DispatchTimerDelegate>)delegate repeats:(BOOL)yesOrNo {
self.delegate = delegate;
if (yesOrNo) {
// 获得队列
dispatch_queue_t queue =dispatch_get_main_queue();
self.timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
dispatch_time_t start =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval *NSEC_PER_SEC));
uint64_t dur = (uint64_t)(interval *NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, dur,0);
// 设置回调
__weakDispatchTimer *wTimer = self;
dispatch_source_set_event_handler(self.timer,^{
//执行事件
DispatchTimer *sTimer = wTimer;
if (sTimer.delegate && [sTimer.delegaterespondsToSelector:@selector(dispatchTimerTask)]) {
[sTimer.delegatedispatchTimerTask];
}
});
// 启动定时器
dispatch_resume(self.timer);
} else {
dispatch_time_t popTime =dispatch_time(DISPATCH_TIME_NOW, interval *NSEC_PER_SEC);
// 设置回调
__weakDispatchTimer *wTimer = self;
dispatch_after(popTime,dispatch_get_main_queue(), ^(void){
//执行事件
DispatchTimer *sTimer = wTimer;
if (sTimer.delegate && [sTimer.delegaterespondsToSelector:@selector(dispatchTimerTask)]) {
[sTimer.delegatedispatchTimerTask];
}
});
}
}
- (void)createDispatchTimerInterval:(NSUInteger)interval block:(DispatchTimerBlock)timerBlock repeats:(BOOL)yesOrNo {
if (yesOrNo) {
// 获得队列
dispatch_queue_t queue =dispatch_get_main_queue();
self.timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
dispatch_time_t start =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 *NSEC_PER_SEC));
uint64_t dur = (uint64_t)(interval *NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, dur,0);
// 设置回调
dispatch_source_set_event_handler(self.timer, timerBlock);
// 启动定时器
dispatch_resume(self.timer);
} else {
dispatch_time_t popTime =dispatch_time(DISPATCH_TIME_NOW, interval *NSEC_PER_SEC);
dispatch_after(popTime,dispatch_get_main_queue(), timerBlock);
}
}
- (void)invalidate {
if (self.timer) {
dispatch_cancel(self.timer);
self.timer =nil;
}
}
@end