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

如有错误,欢迎随时指正!

iOS定时器-- NSTimer 和CADisplaylink的更多相关文章

  1. iOS 定时器 NSTimer、CADisplayLink、GCD3种方式的实现

    在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法.在这个时候,我们就需要用到定时器. 然而,在iOS中有很多方法完成以上的任务,到底有多少种方法呢?经过查阅资 ...

  2. 定时器 NSTimer 和 CADisplayLink

    NSTimer *timer; CADisplayLink *caDisplayLink; int timeCount; - (void)viewDidLoad { [super viewDidLoa ...

  3. iOS定时器NSTimer的使用方法

    1.初始化 + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelect ...

  4. iOS三种定时器的用法NSTimer、CADisplayLink、GCD

    一,NSTimer //创建方式1 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector: ...

  5. iOS - OC NSTimer 定时器

    前言 @interface NSTimer : NSObject 作用 在指定的时间执行指定的任务. 每隔一段时间执行指定的任务. 1.定时器的创建 当定时器创建完(不用 scheduled 的,添加 ...

  6. iOS:三种常见计时器(NSTimer、CADisplayLink、dispatch_source_t)的使用

    一.介绍 在iOS中,计时器是比较常用的,用于统计累加数据或者倒计时等,例如手机号获取验证码.计时器大概有那么三种,分别是:NSTimer.CADisplayLink.dispatch_source_ ...

  7. NSTimer、CADisplayLink、GCD 三种定时器的用法 —— 昉

    在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法.在这个时候,我们就需要用到定时器. 在iOS中有很多方法完成定时器的任务,例如 NSTimer.CADisp ...

  8. [置顶] ios 时间定时器 NSTimer应用demo

    原创文章,转载请注明出处:http://blog.csdn.net/donny_zhang/article/details/9251917 demo功能:ios NSTimer应用demo .ipho ...

  9. iOS定时器的使用

    iOS开发中定时器经常会用到,iOS中常用的定时器有三种,分别是NSTime,CADisplayLink和GCD. NSTimer 方式1 // 创建定时器 NSTimer *timer = [NST ...

随机推荐

  1. shell编程之while死循环

    原文 在linux下编程的程序猿都知道shell脚本,就算你不怎么熟悉,也应该听过的吧!那在shell脚本中的死循环该怎么写呢? 对于熟悉C语言的猿人们来说,最简单的死循环应该这样写: ------- ...

  2. Java 监听器,国际化

    1. 监听器 1.1 概述 监听器: 主要是用来监听特定对象的创建或销毁.属性的变化的! 是一个实现特定接口的普通java类! 对象: 自己创建自己用 (不用监听) 别人创建自己用 (需要监听) Se ...

  3. hive配置参数的说明:

    hive.ddl.output.format:hive的ddl语句的输出格式,默认是text,纯文本,还有json格式,这个是0.90以后才出的新配置: hive.exec.script.wrappe ...

  4. Sort函数的用法

    快速排序sort的用法:(适用于int float double char ...) 记得加头文件! 记得加头文件! 记得加头文件! 头文件: #include <algorithm>   ...

  5. C语言字符串操作函数 - strcpy、strcmp、strcat、反转、回文

    原文:http://www.cnblogs.com/JCSU/articles/1305401.html C语言字符串操作函数 1. 字符串反转 - strRev2. 字符串复制 - strcpy3. ...

  6. day14 HTML CSS

    HTML HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可以让浏 ...

  7. mysql 链接报 Can't connect to MySQL server on 'localhost' (10061)

    之前好好的,重启了下电脑就报了上面的问题... 解决办法很简单:重启下mysql的服务: win7系统,电脑-管理-服务和应用程序-服务,找到mysql重启 即可.

  8. SMBus Host Controller not enabled!

    今天去官网下载最新的ubuntu  ubuntukylin-16.10-desktop-amd64.iso,下载后vm 运行,安装后结果报了这个问题 之后google搜索得到答案: 1.复制   cp ...

  9. 使用spring aop遇到的坑

    1.aop 切点配置无误但只对控制器无效. 检测你的aop开启配置是否放在了spring配置文件中,如果是请把它移到mvc配置文件中. 我们知道当spring项目使用了spring mvc时,项目是存 ...

  10. request.getRequestDispatcher().forward(request.response)

    request.getRequestDispatcher().forward(request.response)中的那两个参数是哪里来的? 2010-11-09 23:13 QQ357169111 | ...