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. UVA 10328(DP,大数,至少连续)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19825 这道题和http://www.cnblogs.com/qlky/p/ ...

  2. 程序员学炒股(6) 让我们来看一下7月份A股的表现

    有了前几天的数据准备,那让我们看一下7月份的股市是牛市还是熊市呢? 牛市和熊市主要就看股票的涨跌分布情况,虽然我们看大盘数据,但是不过中石油占的A股市值太大了,并且中石油95%的股票都是大股东控制的相 ...

  3. java设计模式之工厂模式学习

    上周安排的写两篇设计模式的文章,结果一篇也没写,今天都给写了.回顾+反思.In this world he who stops ,won't get anything he wants! 工厂方法模式 ...

  4. elastic job 动态设置定时任务

    1. 版本 <!-- import elastic-job lite core --> <dependency> <groupId>com.dangdang< ...

  5. js权威指南学习笔记(四)对象

    1.创建对象 (1).通过对象直接量的方式创建 说明:对象直接量是由若干名/值对组成的映射表,名/值对中间用冒号分隔,名/值对之间用逗号分隔,整个映射表用花括号括起来. 如:       5 5   ...

  6. Angular1组件通讯方式总结

    这里需要将Angular1分为Angular1.5之前和Angular1.5两个不同的阶段来讲,两者虽然同属Angular1,但是在开发模式上还是有较大区别的.在Angular1.4及以前,主要是基于 ...

  7. QQ 聊天机器人小薇 2.0.0 发布!

    本次发布主要加入了支持讨论组聊天,并增强了稳定性.另外,官方小薇 QQ 机器人已经下线,大家要体验的话请 自建私服~ 简介 XiaoV(小薇)是一个用 Java 写的 QQ 聊天机器人 Web 服务, ...

  8. 13_Redis安全

    [1.设置密码] [2.绑定IP] [3.命令禁止或重命名] [4.修改默认端口]

  9. QML Delegate中访问该持有者的方式 附加属性(转载)

    http://blog.csdn.net/yuxiaohen/article/details/17226971   用法很奇葩记录一下,实测可以,用于弱化delegate与持有者的依赖 delegat ...

  10. Stack vs Heap

    http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html Table of Contents Stack vs Heap The Stac ...