您的位置:首页 > 移动开发 > IOS开发

iOS基于GCD开发的定时器

2016-07-03 11:38 288 查看
系统提供的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios gcd 调试 内存