前言

 	@interface NSTimer : NSObject

	@interface CADisplayLink : NSObject
  • 作用

    • 在指定的时间执行指定的任务。
    • 每隔一段时间执行指定的任务。

1、定时器的创建

1.1 NSTimer 定时器

  • 当定时器创建完(不用 scheduled 的,添加到 runloop 中)后,该定时器将在初始化时指定的 ti 秒后自动触发。如果 NSTimer 的触发时间到的时候,runloop 在阻塞状态,触发时间就会推迟到下一个 runloop 周期。

  • 1、scheduled 方式

    • 创建并启动定时器。

    • 默认将时钟以 NSDefaultRunLoopMode 模式添加到运行循环。

    • 发生用户交互的时候,时钟会被暂停。

      	/*
      + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti
      target:(id)aTarget
      selector:(SEL)aSelector
      userInfo:(id)userInfo
      repeats:(BOOL)yesOrNo; 参数:
      TimeInterval:触发时间,单位秒
      target:定时起触发对象
      selector:定时器响应方法
      userInfo:用户信息
      repeats:是否重复执行,YES 每个指定的时间重复执行,NO 只执行一次
      */ // 创建并启动定时器
      NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0
      target:self
      selector:@selector(updateTimer:)
      userInfo:nil
      repeats:YES];
  • 2、timer 方式

    • 创建定时器,添加到运行循环后启动定时器。

    • 将时钟以指定的模式添加到运行循环。

      	/*
      + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti
      target:(id)aTarget
      selector:(SEL)aSelector
      userInfo:(nullable id)userInfo
      repeats:(BOOL)yesOrNo; - (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode; NSDefaultRunLoopMode:发生用户交互的时候,时钟会被暂停。时钟,网络。
      NSRunLoopCommonModes:发生用户交互的时候,时钟仍然会触发,如果时钟触发方法非常耗时,
      使用此方式时用户操作会造成非常严重的卡顿。用户交互,响应级别高。
      */ // 创建定时器
      NSTimer *timer = [NSTimer timerWithTimeInterval:2.0
      target:self
      selector:@selector(updateTimer:)
      userInfo:nil
      repeats:YES]; // 将定时器添加到运行循环
      [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

1.2 CADisplayLink 定时器

  • 1、CADisplayLink

    • CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。我们在应用中创建一个新的 CADisplayLink 对象,把它添加到一个 runloop 中,并给它提供一个 target 和 selector 在屏幕刷新的时候调用。

    • 一但 CADisplayLink 以特定的模式注册到 runloop 之后,每当屏幕需要刷新的时候,runloop 就会调用 CADisplayLink 绑定的 target 上的 selector,这时 target 可以读到 CADisplayLink 的每次调用的时间戳,用来准备下一帧显示需要的数据。例如一个视频应用使用时间戳来计算下一帧要显示的视频数据。在 UI 做动画的过程中,需要通过时间戳来计算 UI 对象在动画的下一帧要更新的大小等等。

    • 在添加进 runloop 的时候我们应该选用高一些的优先级,来保证动画的平滑。可以设想一下,我们在动画的过程中,runloop 被添加进来了一个高优先级的任务,那么,下一次的调用就会被暂停转而先去执行高优先级的任务,然后在接着执行 CADisplayLink 的调用,从而造成动画过程的卡顿,使动画不流畅。

    • 另外 CADisplayLink 不能被继承。

    • 属性:

      	duration 	  :提供了每帧之间的时间,也就是屏幕每次刷新之间的的时间。我们可以使用这个时间来计算出下一帧要显示
      的 UI的数值。但是 duration 只是个大概的时间,如果 CPU 忙于其它计算,就没法保证以相同的频率
      执行屏幕的绘制操作,这样会跳过几次调用回调方法的机会。 frameInterval :可读可写的 NSInteger 型值,标识间隔多少帧调用一次 selector 方法,默认值是 1,即每帧都调
      用一次。如果每帧都调用一次的话,对于 iOS 设备来说那刷新频率就是 60HZ 也就是每秒 60 次,如果
      将 frameInterval 设为 2 那么就会两帧调用一次,也就是变成了每秒刷新 30 次。 pause :控制 CADisplayLink 的运行。当我们想结束一个 CADisplayLink 的时候,应该调用
      `- (void)invalidate`从 runloop 中删除并删除之前绑定的 target 跟 selector。
  • 2、CADisplayLink 与 NSTimer 有什么不同

    • iOS 设备的屏幕刷新频率是固定的,CADisplayLink 在正常情况下会在每次刷新结束都被调用,精确度相当高。
    • NSTimer 的精确度就显得低了点,比如 NSTimer 的触发时间到的时候,runloop 如果在阻塞状态,触发时间就会推迟到下一个 runloop 周期。并且 NSTimer 新增了 tolerance 属性,让用户可以设置可以容忍的触发的时间的延迟范围。
    • CADisplayLink 使用场合相对专一,适合做 UI 的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer 的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在 UI 相关的动画或者显示内容使用 CADisplayLink 比起用 NSTimer 的好处就是我们不需要再格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。
  • 3、CADisplayLink 使用示例

    	@property (nonatomic, strong) CADisplayLink *link;
    
    	// 创建定时器
    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(angleChange)];
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; // 开启定时器,默认
    self.link.paused = NO; // 暂停定时器
    self.link.paused = YES; // 定时器触发事件处理
    - (void)angleChange { }
    	@property (nonatomic, strong) CADisplayLink *displayLink;
    
    	self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateTextColor)];
    self.displayLink.paused = YES;
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; - (void)updateTextColor { } - (void)startAnimation {
    self.beginTime = CACurrentMediaTime();
    self.displayLink.paused = NO;
    } - (void)stopAnimation {
    self.displayLink.paused = YES;
    [self.displayLink invalidate];
    self.displayLink = nil;
    }
  • 4、给非 UI 对象添加动画效果

    • 我们知道动画效果就是一个属性的线性变化,比如 UIView 动画的 EasyIn EasyOut 。通过数值按照不同速率的变化我们能生成更接近真实世界的动画效果。我们也可以利用这个特性来使一些其他属性按照我们期望的曲线变化。比如当播放视频时关掉视频的声音我可以通过 CADisplayLink 来实现一个 EasyOut 的渐出效果:先快速的降低音量,在慢慢的渐变到静音。
  • 5、注意

    • 通常来讲:iOS 设备的刷新频率事 60HZ 也就是每秒 60 次。那么每一次刷新的时间就是 1/60 秒 大概 16.7 毫秒。当我们的 frameInterval 值为 1 的时候我们需要保证的是 CADisplayLink 调用的 target 的函数计算时间不应该大于 16.7 否则就会出现严重的丢帧现象。

    • 在 Mac 应用中我们使用的不是 CADisplayLink 而是 CVDisplayLink 它是基于 C 接口的用起来配置有些麻烦但是用起来还是很简单的。

    • Apple 官方的 Demo

    • CADisplayLink Clas Reference

    • 一个类似 Secret 文字渐变效果的开源库

2、定时器的启动与关闭

	// 启动定时器
[timer setFireDate:[NSDate distantPast]]; // 暂停定时器
[timer setFireDate:[NSDate distantFuture]]; // 关闭定时器,永久关闭定时器
[timer invalidate];

3、子线程定时器的创建

  • 在子线程创建定时器时,需要手动开启子线程的运行循环。

    	dispatch_async(dispatch_get_global_queue(0, 0), ^{
    
    		// 在子线程创建定时器
    /*
    scheduled 或 timer 方式创建
    */
    self.timer = [NSTimer timerWithTimeInterval:1.0
    target:self
    selector:@selector(updateTimer:)
    userInfo:nil
    repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode]; // 启动子线程的运行循环
    /*
    这句代码就是一个死循环!如果不停止运行循环,不会执行添加到此句之后的任何代码
    */
    CFRunLoopRun(); // 停止子线程运行循环之前,不会执行添加到此处的任何代码
    });
    	// 定时器执行操作方法
    
    	- (void)updateTimer {
    
    		static int num = 0;
    
    		num++;
    
    		// 满足条件后,停止当前的运行循环
    if (num == 8) { // 停止当前的运行循环
    /*
    一旦停止了运行循环,后续代码能够执行,执行完毕后,线程被自动销毁
    */
    CFRunLoopStop(CFRunLoopGetCurrent());
    }
    }

4、定时任务

  • 1)performSelector

    	// 延时调用
    /*
    1.5 秒后自动调用 self 的 hideHUD 方法
    */
    [self performSelector:@selector(hideHUD) withObject:nil afterDelay:1.5]; // 取消延时调用
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hideHUD) object:nil];
  • 2)GCD

    	// 多线程
    /*
    1.5 秒后自动执行 block 里面的代码
    */
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.hud.alpha = 0.0;
    });
  • 3)NSTimer

    	// 定时器
    /*
    1.5 秒后自动调用 self 的 hideHUD 方法
    */
    [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(hideHUD) userInfo:nil repeats:NO];

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

  1. iOS - Swift NSTimer 定时器

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

  2. IOS OC 多任务定时器 NSRunLoop 管理 NSTimer

    下面有两种做法 1.使用日期组件 NSDateComponents 2.使用NSString 生成一个日期 //  创建一个日历对象 NSCalendar *calendar = [NSCalenda ...

  3. IOS中的NSTimer定时器详解

    /* 在IOS中有多种定时器,这里我对NSTimer定时器做了一个简单的介绍.如果你是小白,你可能会从这篇文章中学习到一些知识,如果你是大牛,请别吝啬你的评论,指出我的不足,你的质疑是对我最大的帮助. ...

  4. iOS中的定时器

    据我所知,iOS中的定时器有两种.一个叫NSTimer,一个叫CADisplayLink.还有一种是使用GCD,不常用,这里就不介绍了. 下边说下两个定时器分别得用法: =============== ...

  5. iOS - OC 面向对象语法

    1.类 1)根类:因为类 NSObject 是层次结构的最顶层,因此称为根类. 可以将类称为子类(subclass)和父类(superclass),也可以将类称为子类和超类. 2)分类/类别(cate ...

  6. ios+oc面试题

    ios+oc面试题     浅复制和深复制的区别?//浅拷贝和深拷贝答案:浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身.//通过对象的指针来访问这个对象深层复制(mutableCo ...

  7. iOS OC语言原生开发的IM模块--RChat

    iOS OC语言原生开发的IM模块,用于项目中需要原生开发IM的情况,具备发送文字.表情.语音.图片.视频等完整功能,包含图片预览视频播放等功能,此项目将会长期更新如有问题可以提出,我的邮箱:fshm ...

  8. 【转】IOS NSTimer 定时器用法总结

    原文网址:http://my.oschina.net/u/2340880/blog/398598 NSTimer在IOS开发中会经常用到,尤其是小型游戏,然而对于初学者时常会注意不到其中的内存释放问题 ...

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

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

随机推荐

  1. editPlus,3.7V 注册码

    editPlus,3.7V 注册码: username:linzhihui password:5A2B6-69740-D9CDE-79702-C9CCD

  2. 线程属性pthread_attr_t

    转:http://blog.sina.com.cn/s/blog_6dc9e4cf0100xcvk.html1.    线程属性:             使用pthread_attr_t类型表示,我 ...

  3. myeclipse 常用快捷键总结

    1 shift+enter 不管鼠标在当前行的什么位置,重新开启一行(向下) 2 shift+ctrl+enter 不管鼠标在当前行的什么位置,重新开启一行(向上) 3 Ctrl+D     删除一行 ...

  4. tar 报错gzip: stdin: not in gzip format

    今天在linux下 用tar -zxvf xxx.tar.bz2 然后就报这个错. gzip: stdin: not in gzip formattar: Child returned status ...

  5. sp_sys_ERPTrigger_base

    USE [GalaxyPointDB24]GO/****** Object:  StoredProcedure [dbo].[sp_zy_Process_scrap]    Script Date: ...

  6. hdu1016 Prime Ring Problem

    dfs,用全局数组和变量保存并更新当前状态. 答案可以直接在搜索结束时打印,n为奇数时方案数为0. acm.hdu.edu.cn/showproblem.php?pid=1016 #include & ...

  7. js实现图片的瀑布流

    先看效果: 初始状态:

  8. 越狱后如何添加cydia源及cydia源大全

    http://jingyan.baidu.com/article/6c67b1d6cc53fe2787bb1e06.html 软件游戏能PJ,插件其实也一样,所以有些源里面就包含了大量的PJ插件~ a ...

  9. 软件密码和https协议

    密码安全问题,一直是程序员最痛疼的问题,这一章主要的来说一下密码的安全,和怎么提高密码的安全,还有Tomcat的https协议. 密码对于一个程序的安全有多重要就不多说了,如果你做过银行系统的话,那么 ...

  10. join(添加字符)与id显示

    #!/usr/bin/env python li = ["alex",'sb'] l1 = "_".join(li) print(l1) print(id(li ...