定时器的几种实现方式
程序员文章站
2024-01-10 14:24:10
...
**一. ios端实现定时器的方式有以下三种方式
1).NSTimer
优点:使用方便,满足大多数需求,应用广泛
缺点:不太精准,受制于RunLoop,使用可能会造成内存泄露
使用:引导页,滑动页等等
2).GCD-Dispatch_source_t
优点:精度较高,系统自动触发,系统级别的源,不受制于RunLoop
缺点:时间事件可能被堵塞
使用:验证消息等待
3).CADisPlayLink
优点:刷新频率和设备屏幕同步,苹果手机屏幕60hz,每秒调用60次,依托设备触发事件,时间间隔最精准的定时器
缺点:CPU销毁过大,影响屏幕刷新,触发也会受影响,不能被继承
使用:和贝塞尔曲线+CAShapeLayer使用
二.具体实现
NSTimer
//创建方式1.默认添加到当前的runlooph中,默认defaultmodel 无需手动添加runloop中,会被其他事件打断
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerUpData) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
//创建方式2
//需要手动添加到runloop中,不会回不执行定时器
_timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerUpData) userInfo:nil repeats:YES];
//方式一默认model,会被打断
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSDefaultRunLoopMode];
//方式二也会被打断
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:UITrackingRunLoopMode];
//方式三 组合model不会内打断
[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
//销毁计时器
[self.timer invalidate];
//暂停计时器
self.timer.fireDate = [NSDate distantFuture];
//恢复计时器
self.timer.fireDate = [NSDate distantPast];
//子线程中使用
__block NSTimer *disTimer;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
disTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerUpData) userInfo:nil repeats:YES];
//启动线程
[[NSRunLoop currentRunLoop] run];
});
dispatch_soucrt
-(void)configDisPathSouorce{
__block int timeOut = 30; //倒计时时间
//创建异步队列,
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//创建定时器
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//开始时间
dispatch_time_t startTime = dispatch_walltime(NULL,1.0*NSEC_PER_SEC);
//间隔时间
uint64_t interval = 1.0*NSEC_PER_SEC;
//每秒执行
dispatch_source_set_timer(timer,startTime, interval,0);
dispatch_source_set_event_handler(timer, ^{
//结束 关闭
if (timeOut<=0) {
dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
//主线程 按钮怎么显示或者挑转等等
});
}else{
int seconds = timeOut%60;
NSString *timeStr = [NSString stringWithFormat:@"%.2d",seconds];
dispatch_async(dispatch_get_main_queue(), ^{
//按钮显示 需求来
NSLog(@"__%@",timeStr);
});
timeOut--;
}
});
dispatch_resume(timer);
}
CADisPlayLink
-(void)configCADisplayLink{
/*
四个属性
timestamp:获取上一次selector被执行的时间蔟,只读,需要selector执行一次之后才有值
duration:获取当前设备屏幕刷新时间的间隔,只读属性,需要selector触发一次后有值
*/
CADisplayLink *displayTime = [CADisplayLink displayLinkWithTarget:self selector:@selector(dispalychange)];
//暂停 yes暂停 no不暂停
displayTime.paused = YES;
//触发间隔 弃用
//displayTime.frameInterval = 2;
//加入到runloop中
[displayTime addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//销毁
// [displayTime invalidate];
}
-(void)dispalychange{
}
```**
上一篇: C语言标准函数库动态内存分配和释放分析
下一篇: 案例1:淘宝网架构演化