iOS学习笔记-137.RunLoop05——Runloop相关类3_CFRunLoopTimerRef(NSTimer)为何定时有时会失败
来源:互联网 发布:淘宝运营应该怎么做 编辑:程序博客网 时间:2024/05/29 09:37
- 一CFRunLoopTimerRef 主要说明
- 二NSTimer定时器不能用了问题演示
- 1 NSTimer定时器不能用了图示
- 2 NSTimer定时器不能用了代码示例1
- 3 NSTimer定时器不能用了代码示例2
- 三NSTimer定时器不能用了解决方式
- 1 问题分析与解决方式说明
- 2 针对 22 中的解决方式1
- 3 针对 22 中的解决方式2
- 4 针对 23 中的解决方式1
- 5 针对 23 中的解决方式2
- 四子线程中使用 NSTimer 定时器
- 1 子线程中不能运行 NSTimer 定时器
- 2 问题分析月解决方式说明
- 3 解决示例代码
- 五GCD定时器不受Runloop的mode的影响
- 1 GCD定时器的使用
- 2 GCD定时器补充
一、CFRunLoopTimerRef 主要说明
CFRunLoopTimerRef是基于时间的触发器
基本上说的就是NSTimer,它会受到runloop的mode的影响
GCD的定时器不受Runloop的mode的影响
二、NSTimer定时器不能用了问题演示
2.1 NSTimer定时器不能用了,图示
2.2 NSTimer定时器不能用了代码示例1
-(void)timer1{ //该方法内部自动添加到runloop中,并且设置运行模式为默认 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES];}
2.3 NSTimer定时器不能用了代码示例2
我们首先在主线程上创建一个定时器,并且把它添加到默认模式下。
-(void)timer2{ //创建定时器 NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; //2.添加定时器到runLoop中,指定runloop的运行模式为NSDefaultRunLoopMode /* 第一个参数:定时器 第二个参数:runloop的运行模式 */ [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];}
三、NSTimer定时器不能用了解决方式
3.1 问题分析与解决方式说明
由前面的学习,我们知道,当我们的 UITextView 滚动的时候,我们主线程的运行模式是 UITrackingRunLoopMode。然而我们的定时器是添加在 NSDefaultRunLoopMode,模式下。它能再 UITrackingRunLoopMode下运行,那不就见鬼了吗?
说了这么多?那么我们的解决方式也就是来了,我们把定时器在添加到 UITrackingRunLoopMode 模式下,不就ok了吗?。除此之外,我们还可以把它添加到 NSRunLoopCommonModes模式下,因为 NSRunLoopCommonModes = NSDefaultRunLoopMode + UITrackingRunLoopMode
3.2 针对 2.2 中的解决方式1
-(void)timer1{ //该方法内部自动添加到runloop中,并且设置运行模式为默认 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; //可以通过如下来修改它的运行模式 [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];}
3.3 针对 2.2 中的解决方式2
推荐这种
-(void)timer1{ //该方法内部自动添加到runloop中,并且设置运行模式为默认 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; //可以通过如下来修改它的运行模式 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];}
3.4 针对 2.3 中的解决方式1
-(void)timer2{ //创建定时器 NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; //2.添加定时器到runLoop中,指定runloop的运行模式为NSDefaultRunLoopMode /* 第一个参数:定时器 第二个参数:runloop的运行模式 */ [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // 3.1 第一种方式,再把它添加到 UITrackingRunLoopMode [[NSRunLoop mainRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];}
3.5 针对 2.3 中的解决方式2
推荐这种
-(void)timer2{ //创建定时器 NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; //NSRunLoopCommonModes = NSDefaultRunLoopMode + UITrackingRunLoopMode //占用,标签,凡是添加到NSRunLoopCommonModes中的事件 都会被同时添加到打上commmon标签的运行模式上 [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];}
四、子线程中使用 NSTimer 定时器
4.1 子线程中不能运行 NSTimer 定时器?
我们创建了如下代码,
-(void)viewDidLoad{ [NSThread detachNewThreadSelector:@selector(timer3) toTarget:self withObject:nil];}-(void)timer3{ //创建一个定时器 //该方法内部自动添加到runloop中,并且设置运行模式为默认 [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES];}
我们发现,我们的定时器,不能工作了?那么怎么解决呢?
4.2 问题分析月解决方式说明
分析上面的问题,我们知道,NSTimer是需要 RunLoop 的。之前我们在主线程中运行创建NSTimer的时候,不需要自己手动来获取RunLoop那是因为,主线程中的 RunLoop 已经自动创建了。然而子线程中的 RunLoop 是需要我们手动创建的。而创建的方法就是调用 currentRunLoop 方法,如实我们就有了解决方案,就是自己创建 RunLoop 并且运行它。
4.3 解决示例代码
于是针对上面的代码,我们就有了下面的解决代码
-(void)timer3{ //子线程中,默认是没有创建 RunLoop 的,可以通过 [NSRunLoop currentRunLoop] 来创建,它其实是一个懒加载 NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; //创建一个定时器 //该方法内部自动添加到runloop中,并且设置运行模式为默认 [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; //让 runloop 运行 [currentRunLoop run];}
除此之外,我们上面scheduledTimerWithTimeInterval,该方法内部自动添加到runloop中,并且设置运行模式为默认,它内部其实已经调用了[NSRunLoop currentRunLoop]
。那么我们直接运行就行了。于是又有
-(void)timer3{ //创建一个定时器 //该方法内部自动添加到runloop中,并且设置运行模式为默认。那么我们可以知道,它内部其实已经调用了[NSRunLoop currentRunLoop] [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(run) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] run];}
五、GCD定时器——不受Runloop的mode的影响
NSTimer 会受到 RunLoop的mode的影响。然而GCD不会。
5.1 GCD定时器的使用。
-(void)gcdTimer{ NSLog(@"%s",__func__); //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 从现在开始计时 第三个参数:间隔时间 1.0 GCD中时间单位为纳秒 第四个参数:精准度 绝对精准0 */ dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.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;}
5.2 GCD定时器补充
DISPATCH_SOURCE_TYPE_TIMER 定时响应(定时器事件)DISPATCH_SOURCE_TYPE_SIGNAL 接收到UNIX信号时响应DISPATCH_SOURCE_TYPE_READ IO操作,如对文件的操作、socket操作的读响应DISPATCH_SOURCE_TYPE_WRITE IO操作,如对文件的操作、socket操作的写响应DISPATCH_SOURCE_TYPE_VNODE 文件状态监听,文件被删除、移动、重命名DISPATCH_SOURCE_TYPE_PROC 进程监听,如进程的退出、创建一个或更多的子线程、进程收到UNIX信号下面两个都属于Mach相关事件响应 DISPATCH_SOURCE_TYPE_MACH_SEND DISPATCH_SOURCE_TYPE_MACH_RECV下面两个都属于自定义的事件,并且也是有自己来触发 DISPATCH_SOURCE_TYPE_DATA_ADD DISPATCH_SOURCE_TYPE_DATA_OR
- iOS学习笔记-137.RunLoop05——Runloop相关类3_CFRunLoopTimerRef(NSTimer)为何定时有时会失败
- iOS学习笔记-135.RunLoop03——Runloop相关类1_基础
- iOS学习笔记-136.RunLoop04——Runloop相关类2_CFRunLoopModeRef
- iOS学习笔记-138.RunLoop06——Runloop相关类4_ CFRunloopSourceRef和CFRunLoopObserverRef
- (iOS开发) RunLoop与NSTimer的相关
- iOS学习笔记12—Runloop
- iOS学习笔记12—Runloop
- iOS学习笔记—Runloop 经典讲解
- iOS学习笔记12—Runloop
- iOS Runloop学习笔记
- iOS-RunLoop学习笔记
- iOS开发学习之NSTimer失效、NSTimer与runloop之间的关系、解密NSTimer
- iOS学习笔记-134.RunLoop02——Runloop与线程
- iOS学习笔记-139.RunLoop07——Runloop处理流程
- iOS 学习笔记 --- RunLoop基础
- 《iOS开发笔记—运行循环RunLoop》
- IOS NStimer,runloop,thread,task小总结 .
- IOS中NSTimer使用及runloop
- 实战10.分布式内存文件系统Tachyon介绍及安装部署
- python读写CSV
- iOS【IOS电商项目: 高仿<爱鲜蜂> OC版】
- Apache Spark2.0正式发布
- Java常用方法总结
- iOS学习笔记-137.RunLoop05——Runloop相关类3_CFRunLoopTimerRef(NSTimer)为何定时有时会失败
- 待补题
- 欢迎使用CSDN-markdown编辑器
- HDU
- Spark源码系列(一)spark-submit提交作业过程
- hdu 6205 card card card
- Typescript中的装饰器原理
- Spark源码系列(二)RDD详解
- PLSQL学习(三) 异常处理