GCD实现支持repeat和repeat次数的定时器,能自动识别seletor参数类型并传出所需参数
提供接口
//默认开启时间为 interval
-(void)lh_setGCDTimerWithTimer:(dispatch_source_t)timer
interVal:(uint64_t)interval
repeat:(BOOL)repat
sel:(SEL)sel;
-(void)lh_setGCDtimerWithTimer:(dispatch_source_t)timer
interval:(uint64_t)interval
repeat:(BOOL)repeat
repeatCountLimit:(NSInteger)count
sel:(SEL)sel
startNow:(BOOL)startNow;
-(void)lh_setGCDtimerWithTimer:(dispatch_source_t)timer
startTime:(uint64_t)startTime
interval:(uint64_t)interval
repeat:(BOOL)repeat
repeatCountLimit:(NSInteger)count
sel:(SEL)sel;
核心代码如下:
/**
GCD定时器
@param timer timer
@param interval interval
@param startTime 启动定时器时间 为当前时间之后多少秒。
@param repeat 是否crepeat
@param countLimit 重复次数限制
@param sel sel
@param startNow 是否立即开始,如果不是的话,开始时间为时间间隔
*/
-(void)lh_innerSetGCDtimerWithTimer:(dispatch_source_t)timer startTime:(uint64_t)startTime interval:(uint64_t)interval repeat:(BOOL)repeat repeatCountLimit:(NSInteger)countLimit sel:(SEL)sel startNow:(BOOL)startNow{
uint64_t startT = startTime;
if (startTime <= 0) {
startT = interval;
}
BOOL needRecord = YES;
if (countLimit == 0 && repeat ==YES) {
needRecord = NO;
}
if (timer == nil) {
return;
}
if (repeat == NO) {
countLimit = 1;
} else {
countLimit = (countLimit < 1) ? MAXFLOAT : countLimit;
}
int j = 0;
if (!startNow) {
j = 1;
}
__block NSInteger i = j;
dispatch_time_t start = startNow ? DISPATCH_TIME_NOW : dispatch_time(DISPATCH_TIME_NOW, startT *NSEC_PER_SEC);
dispatch_source_set_timer(timer,start, interval*NSEC_PER_SEC, 0.1* NSEC_PER_SEC);
__weak typeof(timer)wektimer = timer;
__weak typeof(self)wekSelf = self;
NSMethodSignature *methodSignature = [[wekSelf class] instanceMethodSignatureForSelector:sel];
NSInteger numberOfArguments = methodSignature.numberOfArguments;
IMP imp = [wekSelf methodForSelector:sel];
if (!imp) {
return;
}
dispatch_source_set_event_handler(timer, ^{
IMP imp = [wekSelf methodForSelector:sel];
if(!imp) return;
if (countLimit > 0) {
if (countLimit - i == 0) {
dispatch_cancel(wektimer);
}
}
if (numberOfArguments == 2) {
void (*func)(id, SEL) = (void *)imp;
func(wekSelf,sel);
}else if (numberOfArguments == 3){
const char* type = [methodSignature getArgumentTypeAtIndex:2];
if (type[0] == 'q' || type[0] == 'i') {
void (*func)(id, SEL,NSInteger) = (void *)imp;
func(wekSelf,sel,i);
}
if (type[0] == '@') {
void (*func)(id, SEL,id) = (void *)imp;
func(wekSelf,sel,@{@"i":@(i),@"countLimit":@(countLimit)});
}
}else if (numberOfArguments >3){
const char* typeF = [methodSignature getArgumentTypeAtIndex:2];
const char* typeN = [methodSignature getArgumentTypeAtIndex:3];
if ((typeF[0] == 'q' || typeF[0] == 'i' )&& (typeN[0] == 'q' || typeN[0] == 'i' ) ) {
void (*func)(id, SEL,NSInteger,NSInteger) = (void *)imp;
func(wekSelf,sel,i,countLimit);
}else if (typeF[0] == '@' ){
void (*func)(id, SEL,id) = (void *)imp;
func(wekSelf,sel,@{@"i":@(i),@"countLimit":@(countLimit)});
}else if ((typeF[0] == 'i' || typeF[0] == 'q') &&((typeN[0]=='i')&&(typeN[0]!='q'))){
void (*func)(id, SEL,NSInteger) = (void *)imp;
func(wekSelf,sel,i);
}
}
if (needRecord) {
i++;
}
});
dispatch_resume(timer);
}
如有错误,请不吝指出。
邮箱:15652628678@163.com