iOS定时器-- NSTimer 和CADisplaylink
iOS定时器-- NSTimer 和CADisplaylink
一、iOS中有两种不同的定时器:
1. NSTimer(时间间隔可以任意设定,最小0.1ms)// If seconds is less than or equal to 0.0, this method chooses the nonnegative value of 0.1 milliseconds instead.
2. CADisplayLink(时间间隔不能设置,与显示器刷新频率一直)
二、创建和启动定时器的3种方式:
// 方式1
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(nextImage) userInfo:nil repeats:YES]; //会自动加入当前的runloop消息循环中,不用手写[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
// 方式2
// 创建 NSTimer 对象
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(test1) userInfo:nil repeats:YES];
//将刚创建的 NSTimer 对象加到消息循环中, 这样就会自动启动定时器
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSRunLoopCommonModes];
// 方式3
// 创建计时器对象
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(test1) userInfo:nil repeats:YES]
// 每次调用一次 fire 执行一次 test1方法
[timer fire]; // 执行一次 test 方法
[timer fire]; // 执行一次 test 方法
[timer fire]; // 执行一次 test 方法
[timer fire]; // 执行一次 test 方法
三、关于NSRunLoop相关知识:
先看看NSTimer的两个常用方法:
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer但不执行
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer并且纳入当前线程的run loop来执行
NSRunLoop与timer有关方法为:
- (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode; //在run loop上注册timer
理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的。
主线程已经有run loop,所以NSTimer一般在主线程上运行都不必再调用addTimer: 。
但在非主线程上运行必须配置run loop,NSTimer在非主线程的main方法中使用,示例代码如下:
- (void)main
{
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:myTimer forMode:NSDefaultRunLoopMode]; //实际上这步是不需要,scheduledTimerWithTimeInterval已经纳入当前线程运行。如果使用timerWithTimeInterval则需要
while (xxx条件)
[runLoop run];
}
实际上这个线程无法退出,因为有timer事件需要处理,[runLoop run]会一直无法返回。解决办法就是设置一个截止时间:
[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //每隔10秒检查下线程循环条件,当然时间值可以根据实际情况来定。
特别注意:
我们通常在主线程中使用NSTimer,有个实际遇到的问题需要注意。当滑动界面时,系统为了更好地处理UI事件和滚动显示,主线程runloop会暂时停止处理一些其它事件,这时主线程中运行的NSTimer就会被暂停。解决办法就是改变NSTimer运行的mode(mode可以看成事件类型),不使用缺省的NSDefaultRunLoopMode,而是改用NSRunLoopCommonModes,这样主线程就会继续处理NSTimer事件了。具体代码如下:
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
ios开发经常用到的延迟调用的方法,其实就是在当前线程的run loop上注册timer来实现定时运行的。所以如果是在非主线程上使用,一定要有一个run loop。
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
四、关于CADisplaylink相关知识
注意:
严格意义上讲 CADisplayLink 并不是计时器控件, 它是与显示器刷新频率一致的。比如显示的刷新频率是60赫兹, 那么 CADisplayLink 就会每秒钟执行60次。正是因为这个原因所以有时也把 CADisplayLink 当做计时器控件来使用。CADisplayLink:每次屏幕刷新的时候就会调用,屏幕一般一秒刷新60次。
//CADisplayLink应用举例
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timerAction)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; // 添加主运行循环
- (void)timerAction
{ // 注意:这个方法并不会马上调用drawRect,其实这个方法只是给当前控件添加刷新的标记,等下一次屏幕刷新的时候才会调用drawRect
[self setNeedsDisplay];
}
//如果想把一些文字/图片等绘制在自定义的WZView上,必须在drawRect里写代码
- (void)drawRect:(CGRect)rect {
// 如果以后想绘制东西到view上面,必须在drawRect方法里面,不管有没有手动获取到上下文
UIImage *image = [UIImage imageNamed:@"雪花"];
[image drawAtPoint:CGPointMake(50, _snowY)];
}
五、NSTimer 和CADisplaylink的区别:
1. 如果在绘图的时候需要用到定时器,通常CADisplaylink, NSTimer很少用于绘图,因为调度优先级比较低,并不会准时调用。
2. 使用绘图产生动画时,一般用CADisplaylink定时器在@selector(timerAction:)方法里调用[self setNeedsDisplay];方法,因为CADisplaylink是在屏幕刷新时调用一次timerAction:方法,而setNeedsDisplay方法也是在屏幕刷新时调用drawRect方法重绘图形,二者刚好同步。这样产生的动画就非常流畅,不会有卡顿的感觉。
文章系作者原创,转载请注明出处:http://www.cnblogs.com/stevenwuzheng/p/5213908.html
如有错误,欢迎随时指正!
转载于:https://www.cnblogs.com/stevenwuzheng/p/5213908.html
iOS定时器-- NSTimer 和CADisplaylink相关推荐
- IOS 定时器 NSTimer
定时器对象,在OC中,定时器对象是NSTimer类型 //ViewController.h #import <UIKit/UIKit> @interface ViewController: ...
- iOS之深入探究CADisplayLink和NSTimer的对比和内存溢出问题
CADisplayLink的基本说明和使用 一.什么是CADisplayLink? 简单地说,它就是一个定时器,每隔几毫秒刷新一次屏幕. CADisplayLink是一个能让我们以和屏幕刷新率相同的频 ...
- NSTimer、CADisplayLink、GCD 三种定时器的用法 —— 昉
在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法.在这个时候,我们就需要用到定时器. 在iOS中有很多方法完成定时器的任务,例如 NSTimer.CADisp ...
- iOS的三种常见计时器(NStimer、CADisplayLink、dispatch_source_t)的使用
一.介绍 在iOS中,计时器是比较常用的,用于统计累加数据或者倒计时等,例如手机号获取验证码.计时器大概有那么三种,分别是:NSTimer.CADisplayLink.dispatch_source_ ...
- iOS开发 NSTimer定时器
目录 前言 NSTimer是什么 NSTimer怎么使用 创建NSTimer 触发NSTimer 销毁NSTimer NSTimer与runloop NSTimer与performSelector:w ...
- iOS中定时器NSTimer的开启与关闭
调用一次计时器方法: [cpp] view plain copy myTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self ...
- iOS中定时器NSTimer的使用
1.初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelect ...
- ios nstimer实现延时_iOS中定时器NSTimer的使用
1.初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelect ...
- IOS中定时器NSTimer
调用一次计时器方法: [cpp] view plain copy myTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:sel ...
最新文章
- 基于点云强度的3D激光雷达与相机的外参标定
- Windows 2008 部署服务之Windows 7 应答文件创建
- 图论-最短路Dijkstra算法详解超详 有图解
- leetcode 35. 搜索插入位置
- JMX之模型MBean
- mysql事务实战_mysql事务隔离级别详解和实战
- android123 zhihuibeijing 新闻中心-新闻 页签 ViewPagerIndicator实现
- centos7 postgresql9和postgis2.1插件编译部署
- 最近项目中遇到的一个算法挑战
- 远程下层文档 正在打印_爱普生上线智能打印“宅家学习”好物选择就来京东电脑数码...
- spark sql 数据类型转换_spark dataframe 类型转换
- 计算机安全模式win7,win7安全模式下怎么恢复系统
- spring事务的传播行为的讲解(笔记 侵删)
- 若依(RuoYi-Vue)+Flowable工作流前后端整合教程
- 黄一老师:财商思维、信用融资能对你有什么帮助?
- NMOS管和PMOS管做开关控制电路
- 解决selenium遇到火狐浏览器自动打开下载文件
- 力扣算法学习计划打卡:第三天
- Android图片特效处理(像素处理)
- 读史记——刘敬叔孙通列传第三十九(1)
热门文章
- VM虚拟机中CentOS6.4操作系统安装一
- 为什么单例模式是邪恶的(译)
- GIS开源程序收集(转载)
- Java IO - Reader
- mysql select null 0,查询值中为NULL,在MySQL中产生0.00
- qml如何发布程序_首创PC端小程序直播发布会,360如何与手机厂商一起共振?
- wxpython图形编程_wxpython 图像编程
- 如何利用火狐获取网址中的提交链接
- 计算机图形相关输出设备,计算机图形输出设备.ppt
- Android面试题Service,Android面试题-IntentService源码分析