GCD定時器的優勢是不受RunLoop的運行模式的影響,它的的間隔時間是納秒為單位。
GCDTimer.h
#import <Foundation/Foundation.h>
typedef void (^TimerRunBlock)(NSUInteger currentTime); //定時器計時回調
typedef void (^TimerStopBlock)(); //定時器結束計時回調
@interface DPGCDTimer : NSObject
@property (nonatomic,assign)BOOL isTimerRuning; //定時器是否正在運行
@property (nonatomic, copy) TimerStopBlock timerStopBlock;
/**
* 定時器初始化(定時器默認開啟)
*
* @param timeDuration 時長
* @param timerRunBlock 定時器回調
*/
- (void)timerWithTimeDuration:(double)timeDuration withRunBlock:(TimerRunBlock)timerRunBlock;
/**
* 定時器停止
*/
- (void)stopTimer;
/**
* 定時器恢復
*/
- (void)resumeTimer;
/**
* 定時器暫停
*/
- (void)suspendTimer;
@end
#import "DPGCDTimer.h"
#define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;
@interface DPGCDTimer ()
{
dispatch_source_t __block timer;
}
@property (nonatomic,copy)TimerRunBlock timerRunBlock;
@end
@implementation DPGCDTimer
- (void)timerWithTimeDuration:(double)timeDuration withRunBlock:(TimerRunBlock)timerRunBlock
{
if (!timer) {
WS(weakSelf);
//創建定時器
_isTimerRuning = YES;
NSUInteger __block time = timeDuration;
self.timerRunBlock = timerRunBlock;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(timer,dispatch_walltime(NULL, 0),1 * NSEC_PER_SEC, 0); //每秒執行
dispatch_source_set_event_handler(timer, ^{
if (time <= 0) {
[self stopTimer];
} else {
if (weakSelf.timerRunBlock) {
weakSelf.timerRunBlock(time --);
}
}
});
dispatch_resume(timer);
}
}
//停止
- (void)stopTimer
{
if(timer){
if (_isTimerRuning) {
dispatch_source_cancel(timer);
timer = nil;
_isTimerRuning = NO;
if (self.timerStopBlock) {
self.timerStopBlock();
}
}
}
}
//恢復
- (void)resumeTimer
{
if(timer){
if (!_isTimerRuning) {
dispatch_resume(timer);
_isTimerRuning = YES;
}
}
}
//暫停
- (void)suspendTimer
{
if(timer){
if (_isTimerRuning) {
dispatch_suspend(timer);
_isTimerRuning = NO;
}
}
}
@end
PS:
GCD 中刷新UI導致線程崩潰問題工具 - PSPDFUIKitMainThreadGuard
工具使用方法就是把這個.m文件拖入工程,如果有問題就會PSPDFAssert
斷點處停住。在左側線程分析中點擊查看出現錯誤的地方。