美文网首页
关于定时器

关于定时器

作者: 攻克乃还_ | 来源:发表于2017-10-02 10:49 被阅读3次
1.NSTimer的创建
  • 常用方法一:该方法内部自动添加到runloop中, 运行模式为默认
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];

// 如果在子线程中调用改方法,不会执行,因为子线程runloop必须手动开启:
dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(repeat:) userInfo:@{@"key":@"value"} repeats:true]; 
// 子线程runloop手动开启
[[NSRunLoop currentRunLoop] run]; 
});
  • 不常用方法二:该方法创建的NSTimer必须手动添加到runloop中
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[runloop addTimer:timer forMode:NSDefaultRunLoopMode];
  • 不常用方法三:两个方法创建的NSTimer必须手动添加到runloop中
- (instancetype)initWithFireDate: interval: target: selector: userInfo: repeats:
- (void)initWithFireDate: interval: repeats: block:
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
2.NSTimer与Runloop:
  • 为什么NSTimer要添加到Runloop:
    • NSTimer是一种source,所以的source要起作用,都要添加到runloop中
  • 如果添加到了kCFRunLoopDefaultMode模式中,在拖动界面的时候,runloop模式只能唯一,这时切换为UITrackingRunLoopMode,定时器停止工作
  • 如果添加到了kCFRunLoopCommonModes模式中,任何runloop模式都可以工作了
    • Runloop的三种模式:
// 默认模式
kCFRunLoopDefaultMode
// 拖动模式
UITrackingRunLoopMode
// 此模式包含了以上两种模式
kCFRunLoopCommonModes
3.NSTimer的循环引用
  • 创建NSTimer时,最后一个参数如果为YES,那么NSTimer对于target:self形成强引用;而self因为后续要用到定时器,所以对于定时器也形成了强引用;这就形成了循环引用
  • 如果我们启动了一个NSTimer,在某个界面释放前,将这个NSTimer停止,甚至置为nil,都不能使这个界面释放,原因是系统的循环池中还保有这个对象
4.如何解决循环引用

4.1.控制器不再引用NSTimer
4.2.NSTimer不再引用控制器

  • fire方法
    • 启动 Timer, 触发Target的方法调用但是并不会改变Timer的时间设置。 如果定时器的方法是non-repeating,调用之后自动销毁
- (void)fire;
  • 销毁NSTimer的唯一办法:(nstimer的创建和销毁要在一个runloop中)
// 要在dealloc方法调用之前销毁NSTimer
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if (timer.isValid) {
    // 从runloop中销毁,销毁系统对于NSTimer的强引用
    [_timer invalidate];
    // 将属性置空销毁,销毁self对于NSTimer的强引用
    _timer = nil;
}
}
.5.GCD定时器
  • GCD 绝对精准,不受runloop影响
#import "ViewController.h"

@interface ViewController ()
/** 定时器属性 */
@property (nonatomic, strong) dispatch_source_t timer;
@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1.创建GCD中的定时器
    /*
     第一个参数: source的类型DISPATCH_SOURCE_TYPE_TIMER 表示是定时器
     第二个参数: 描述信息,线程ID
     第三个参数: 更详细的描述信息
     第四个参数: 队列,决定GCD定时器中的任务在哪个线程中执行
     */
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    
    //2.设置定时器(起始时间|间隔时间|精准度)
    /*
     第一个参数:定时器对象
     第二个参数:起始时间,DISPATCH_TIME_NOW 从现在开始计时
     第三个参数:间隔时间 2.0 GCD中时间单位为纳秒
     第四个参数:精准度 绝对精准0
     */
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    
    //3.设置定时器执行的任务
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"GCD---%@",[NSThread currentThread]);
    });
    
    //4.启动执行
    dispatch_resume(timer);
    
    self.timer = timer;
}
@end

6.CADisplayLink定时器

  • 创建CADisplayLink定时器
self.displayLink = [CADisplayLink displayLinkWithTarget:self sel:ector:@selector(handleDisplaylink:)]; 
[self.displayLink addToRunLoop:[NSRunLoop curentRunLoop] forMode:NSDefaultRunLoopMode];
  • 停止CADisplayLink定时器
[self.displayLink invailidate];
self.displayLink = nil;
  • 把CADisplayLink添加到runloop中后,方法就会被周期性调用。invailidate后,CADisplayLink从runloop中移除,方法停止调用

  • 使用场景:

    • 以屏幕的刷新频率执行某操作(刷新频率通常为60次/秒)
    • 界面重绘,比如视频播放
  • CADisplayLink延迟问题

    • 如果执行的操作比较费时,会出现跳过执行操作的情况

相关文章

  • #JS#定时器

    javascritp中有两个关于定时器的专用函数: 倒计定时器timename=setTimeout("funct...

  • 【菜鸟必看】stm32定时器的妙用

    摘要:本文为你带来关于stm32定时器的使用的便利和优势之处。 使用定时器去计算获取一条的时间 一、初步了解定时器...

  • 定时器

    在javascritp中,有两个关于定时器的专用函数,分别为:1.倒计定时器:timename=setTimeou...

  • JS高级定时器

    高级定时器 关于定时器要记住的最重要的事情是:指定的时间间隔表示何时将定时器的代码添加到队列,而不是何时实际执行代...

  • 《嵌入式-STM32开发指南》第二部分 基础篇 - 第2章 Sy

    关于STM32 的时钟系统,Systick系统定时器工作原理分析以及Systick系统定时器寄存器分析请看笔者的上...

  • CEPH中定时器使用

    CEPH中类SafeTimer实现了定时器的功能,关于SafeTimer有很多介绍,但是关于SafeTimer使用...

  • iOS-内存管理1-定时器、NSProxy

    一. CADisplayLink、NSTimer 代码如下: 关于上面两个定时器: CADisplayLink这个...

  • 关于定时器

    1.NSTimer的创建 常用方法一:该方法内部自动添加到runloop中, 运行模式为默认 不常用方法二:该方法...

  • 关于定时器

  • 运动

    【运动】 开个定时器不断改变物体的某个样式 关于定时器的时间: 为什么选30 20-40 1、人眼能接受的时间 ...

网友评论

      本文标题:关于定时器

      本文链接:https://www.haomeiwen.com/subject/toaaextx.html