博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NSTimer与NSRunLoop的关系分析
阅读量:5236 次
发布时间:2019-06-14

本文共 2733 字,大约阅读时间需要 9 分钟。

NSTimer与NSRunLoop的关系分析

最近关于NSTimer和NSRunLoop的关系,做了一个小试验。代码地址:

代码运行效果如下图所示:

本示例演示了四个定时器的效果以及界面操作对它们的影响。

前两个定时器,是在子线程中启动的:

- (void)subThread1{    @autoreleasepool {        self.subThreadTimer1 = [NSTimer scheduledTimerWithTimeInterval:1.0f                                                                target:self                                                              selector:@selector(subThread1Fun:)                                                              userInfo:nil                                                               repeats:YES];    }}- (void)subThread2{    @autoreleasepool {        self.subThreadTimer2 = [NSTimer scheduledTimerWithTimeInterval:1.0f                                                                target:self                                                              selector:@selector(subThread2Fun:)                                                              userInfo:nil                                                               repeats:YES];        [[NSRunLoop currentRunLoop] run]; // 这行代码是两个定时器启动的不同之处    }}

但是从运行效果看,第一个标签数字没有变化,一直是0,明显是定时器没有执行到。

两者的区别在于第二个多执行了一行代码:[[NSRunLoop currentRunLoop] run];
因为NSRunLoop在主线程中是默认运行的,子线程中默认不运行。所以在第一个定时器中,虽然设置了定时器,但出了该线程方法,runLoop默认停止了,异步的方法也就执行不到了。
第二个定时器,在线程中显示把runLoop运行起来了,它会一直运行下去,直到异步方法执行完毕。

下面比较第三,四两个定时器的效果:

- (void)startDefaultRunTimer{    self.defaultRunTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f                                                            target:self                                                          selector:@selector(defaultRunFun:)                                                          userInfo:nil                                                           repeats:YES];}- (void)startCommonRunTimer{    self.commonRunTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f                                                            target:self                                                          selector:@selector(commonRunFun:)                                                          userInfo:nil                                                           repeats:YES];    // 下面一行代码是这两个定时器启动的不同之处    [[NSRunLoop currentRunLoop] addTimer:self.commonRunTimer forMode:NSRunLoopCommonModes]; }

从开始运行,这两个定时器没有什么不同之处。但是当我把手指按在下面左侧的滚动条上上下拖动滚动视图时,这时为了更清楚一看到区别,手指不要离开屏幕。能看到第三个标签数字停止变化,即定时器方法暂停执行了,松开手指后,数字继续变化。

两个定时器的区别在于这句话:[[NSRunLoop currentRunLoop] addTimer:self.commonRunTimer forMode:NSRunLoopCommonModes];
因为runLoop默认的运行模式是:NSDefaultRunLoopMode。在iOS系统下,为了提高界面的响应速度,在用于对屏幕进行操作时,会暂停一些运算,尤其是涉及到滚动视图这种需要流畅响应的视图。
用手拖动右侧滚动试图没有影响,因为它不会上下滚动。
所以我们显示地把这个定时器加到NSRunLoopCommonModes运行模式下,就会忽略界面操作的影响,可以不受界面操作的干扰,正常执行异步方法了。

转载于:https://www.cnblogs.com/yingkong1987/p/3161132.html

你可能感兴趣的文章
游戏偶感
查看>>
Leetcode: Unique Binary Search Trees II
查看>>
C++ FFLIB 之FFDB: 使用 Mysql&Sqlite 实现CRUD
查看>>
Spring-hibernate整合
查看>>
c++ map
查看>>
exit和return的区别
查看>>
discuz 常用脚本格式化数据
查看>>
洛谷P2777
查看>>
PHPStorm2017设置字体与设置浏览器访问
查看>>
SQL查询总结 - wanglei
查看>>
安装cocoa pods时出现Operation not permitted - /usr/bin/xcodeproj的问题
查看>>
GIT笔记:将项目发布到码云
查看>>
JavaScript:学习笔记(7)——VAR、LET、CONST三种变量声明的区别
查看>>
JavaScript 鸭子模型
查看>>
SQL Server 如何查询表定义的列和索引信息
查看>>
GCD 之线程死锁
查看>>
NoSQL数据库常见分类
查看>>
一题多解 之 Bat
查看>>
Java 内部类
查看>>
{面试题7: 使用两个队列实现一个栈}
查看>>