实现一个基于GCD的定时器

前言

NSTimer的特性(坑)上篇文章 提到过,基于这些特性(坑),用GCD写的定时器似乎更好用?

正文

先看API

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, JKGCDTimerState) {
    JKGCDTimerStateSuspend = 0,
    JKGCDTimerStateResume,
    JKGCDTimerStateInvalid
};

@interface JKGCDTimer : NSObject

// default is JKGCDTimerStateSuspend
@property (nonatomic, readonly) JKGCDTimerState state;
@property (nonatomic, readonly) NSTimeInterval interval;
@property (nonatomic, strong, readonly) id userInfo;
@property (nonatomic, readonly) BOOL repeats;
@property (nonatomic, copy, readonly) void(^block)(JKGCDTimer *);


// default is mainQueue
+ (instancetype)timerWithTimeInterval:(NSTimeInterval)interval
                             userInfo:(id)userInfo
                              repeats:(BOOL)repeats
                                block:(void (^)(JKGCDTimer *timer))block;

+ (instancetype)timerWithTimeInterval:(NSTimeInterval)interval
                             userInfo:(id)userInfo
                              repeats:(BOOL)repeats
                                queue:(dispatch_queue_t)queue
                                block:(void (^)(JKGCDTimer *timer))block;

// default is mainQueue
+ (instancetype)scheduledTimerWithTimeInterval:(NSTimeInterval)interval
                             userInfo:(id)userInfo
                              repeats:(BOOL)repeats
                                block:(void (^)(JKGCDTimer *timer))block;

+ (instancetype)scheduledTimerWithTimeInterval:(NSTimeInterval)interval
                             userInfo:(id)userInfo
                              repeats:(BOOL)repeats
                                queue:(dispatch_queue_t)queue
                                block:(void (^)(JKGCDTimer *timer))block;


// the following 3 methods are default invoked in the queue
- (void)suspend;
- (void)resume;
- (void)invalidate;

@end

NS_ASSUME_NONNULL_END

接口基本与NSTimer相同,简单说下特性(坑):
1.timerWithTimeInterval开头的方法需要手动调用resume开启
2.scheduledTimerWithTimeInterval开头的方法默认开启resume
3.可以通过state属性获取当前定时器所处状态
4.通过userInfo属性传递参数
5.在不使用时,需要调用invalidate,可以直接在vc的dealloc方法中调用,不存在内存泄漏
6.repeats为NO时,可以不手动调用invalidate方法,内部默认调用
7.repeats为YES时,可以通过suspendresume对定时器做暂停、恢复操作
8.可以通过queue设置定时器工作所在队列
9.当queue不是主队列,suspend resume invalidate这3个方法可以直接调用,内部已经切换到指定队列,不需要手动切换

这里是源码

随手写的,不保证质量,仅供参看,欢迎指正


Have fun!

你可能感兴趣的:(实现一个基于GCD的定时器)