当前位置: 首页 > article >正文

NSTimer介绍

1.创建NSTimer

常用方法有

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats;+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats;- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats;

他们的区别:

scheduledTimerWithTimeInterval相比它的小伙伴们不仅仅是创建了NSTimer对象, 还把该对象加入到了当前的runloop中!

NSTimer只有被加入到runloop, 才会生效, 即NSTimer才会被真正执行

所以说, 如果你想使用timerWithTimeInterval或initWithFireDate的话, 需要使用NSRunloop的以下方法将NSTimer加入到runloop中

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode

要让timer生效,必须保证该线程的runloop已启动,而且其运行的runloopmode也要匹配。

每一个线程都有它自己的runloop,程序的主线程会自动的使runloop生效,

但对于我们自己新建的线程,它的runloop是不会自己运行起来,当我们需要使用它的runloop时,就得自己启动。

runloop会运行在不同的mode, 简单来说有以下两种mode

NSDefaultRunLoopMode, 默认的mode

UITrackingRunLoopMode, 当处理UI滚动操作时的mode

主线程默认运行在NSDefaultRunLoopMode

在UI滚动时, runloop运行在UITrackingRunLoopMode

如果addTimerforMode是NSDefaultRunLoopMode,那么在UITrackingRunLoopMode下定时器就不运行

要想在这些场景下仍然及时触发NSTimer那应该怎么办呢?

应该使用NSRunLoopCommonModes,包含以上2个mode

[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

例子

//创建一个定时器,_timer=[NSTimer timerWithTimeInterval:10 target:self selector:@selector(changeTimeAtTimedisplay) userInfo:nil repeats:YES];//手动加入到循环中NSRunLoop *runloop=[NSRunLoop currentRunLoop];[runloop addTimer:_timer forMode:NSRunLoopCommonModes];

当然这个定时器会自动启动,只不多过了十秒之后,才触发

fire的作用是提前触发定时器 ,如果执行

_timer.fireDate = CFAbsoluteTimeGetCurrent() + timeInterval;

那么会立即开始定时

2.销毁NSTimer

是否可以将NSTimer置nil, 而让iOS系统帮我们销毁NSTimer呢?

答案是: 不可以

原因:为了保证timer在未来触发指定事件时指定方法是有效的,将指定方法的接收者retain了一份。(重复性还是一次性的timer都是)

如果在VC在创建的NSTimer,VC会和timer相互强引用,VC的dealloc方法不会执行

[_timer invalidate]; // 可以打破相互强引用,真正销毁NSTimer对象_timer = nil; // 对象置nil是一种规范和习惯

所以这段代码不能放在VC的dealloc方法中,可以放在VC的ViewWillDisappear方法中

3.NSTimer会是准时触发事件吗

答案是否定的。

NSTimer不是一个实时系统,因此不管是一次性的还是周期性的timer的实际触发事件的时间可能都会跟我们预想的会有出入。差距的大小跟当前我们程序的执行情况有关系,比如可能程序是多线程的,而你的timer只是添加在某一个线程的runloop的某一种指定的runloopmode中,由于多线程通常都是分时执行的,而且每次执行的mode也可能随着实际情况发生变化。

  假设你添加了一个timer指定2秒后触发某一个事件,但是签好那个时候当前线程在执行一个连续运算(例如大数据块的处理等),这个时候timer就会延迟到该连续运算执行完以后才会执行。重复性的timer遇到这种情况,如果延迟超过了一个周期,则会和后面的触发进行合并,即在一个周期内只会触发一次。但是不管该timer的触发时间延迟的有多离谱,他后面的timer的触发时间总是倍数于第一次添加timer的间隙。

4.BlocksKit中为NSTimer 写的分类

@implementation NSTimer (BlocksKit)+ (instancetype)bk_scheduleTimerWithTimeInterval:(NSTimeInterval)seconds repeats:(BOOL)repeats usingBlock:(void (^)(NSTimer *timer))block{NSTimer *timer = [self bk_timerWithTimeInterval:seconds repeats:repeats usingBlock:block];[NSRunLoop.currentRunLoop addTimer:timer forMode:NSDefaultRunLoopMode];return timer;}+ (instancetype)bk_timerWithTimeInterval:(NSTimeInterval)inSeconds repeats:(BOOL)repeats usingBlock:(void (^)(NSTimer *timer))block{NSParameterAssert(block != nil);CFAbsoluteTime seconds = fmax(inSeconds, 0.0001);CFAbsoluteTime interval = repeats ? seconds : 0;CFAbsoluteTime fireDate = CFAbsoluteTimeGetCurrent() + seconds;return (__bridge_transfer NSTimer *)CFRunLoopTimerCreateWithHandler(NULL, fireDate, interval, 0, 0, (void(^)(CFRunLoopTimerRef))block);}

http://www.lryc.cn/news/2416563.html

相关文章:

  • 【C语言深度剖析】深入理解C语言中的移位操作符(代码+图解)
  • 群体智能优化算法之人工鱼群优化算法(Artificial Fish Swarm Algorithm,AFSA)
  • 视频下载网址
  • 为用户“NT AUTHORITY/NETWORK SERVICE”授予的权限不足,无法执行此操作。 (rsAccessDenied)
  • OMG Data Distribution Service(DDS)规范解读-Part2
  • 2020最新Spring框架教程【IDEA版】-Spring框架从入门到精通
  • TC流量控制
  • 2023最新PHP短网址短链接生成源码
  • NOIP2022 喵了个喵
  • Android AOSP LatinIME输入法自定义图片按钮
  • ExitProcess,TerminateProcess,CreateToolhelp32Snapshot,Process32First,Process32Next,OpenProcess
  • windows进程 windows多进程编程
  • JavaScript之表单验证
  • 从零开始了解《间之楔动漫》:带你领略这部作品的独特魅力!
  • 光盘加密大师轻松为光盘加密
  • 一个简单的TODO,原来这么好用
  • a标签href属性的用法
  • #python学习笔记(五)#循环语句
  • 微信小程序毕业设计-网上商城系统项目开发实例(附源码+演示视频+LW)
  • 怎么使用bootstrap
  • 微软官方原版win7(64位/32位)旗舰版系统下载【适合所有品牌】
  • NVIDIA Jetson TX1(3)
  • 参考文献类型标识码--中英文对照
  • 虚拟机常规使用及网络配置
  • AppSettings和ConnectionStrings的使用。
  • 十大监控电脑桌面的软件,电脑监控软件就它了
  • history对象,当前url添加参数且不刷新页面
  • 实例方法、类方法、静态方法的区别
  • CString中Left,Right,ReverseFind 用法
  • LINUX防火墙Firewall常用命令(非常详细)零基础入门到精通,收藏这一篇就够了