iOS多线程的初步研究(四)-- NSTimer
理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的。
先看看NSTimer的两个常用方法:
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer但不执行
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer并且纳入当前线程的run loop来执行
NSRunLoop与timer有关方法为:
- (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode; //在run loop上注册timer
主线程已经有run loop,所以NSTimer一般在主线程上运行都不必再调用addTimer:。但在非主线程上运行必须配置run loop,该线程的main方法示例代码如下:
- (void)main
{
NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:myTimer forMode:NSDefaultRunLoopMode]; //实际上这步是不需要,scheduledTimerWithTimeInterval已经纳入当前线程运行。如果使用timerWithTimeInterval则需要
while (condition)
[runLoop run];
}
实际上这个线程无法退出,因为有timer事件需要处理,[runLoop run]会一直无法返回。解决办法就是设置一个截止时间:
[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //每隔10秒检查下线程循环条件,当然时间值可以根据实际情况来定。
我们通常在主线程中使用NSTimer,有个实际遇到的问题需要注意。当滑动界面时,系统为了更好地处理UI事件和滚动显示,主线程runloop会暂时停止处理一些其它事件,这时主线程中运行的NSTimer就会被暂停。解决办法就是改变NSTimer运行的mode(mode可以看成事件类型),不使用缺省的NSDefaultRunLoopMode,而是改用NSRunLoopCommonModes,这样主线程就会继续处理NSTimer事件了。具体代码如下:
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
大家可以参看博文http://bluevt.org/?p=209,加深理解NSTimer和NSRunLoop的关系。
以前博文中提到延迟调用的方法,其实就是在当前线程的run loop上注册timer来实现定时运行的。所以如果是在非主线程上使用,一定要有一个run loop。
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
iOS多线程的初步研究(四)-- NSTimer的更多相关文章
- iOS多线程的初步研究
iOS多线程的初步研究(四) 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NST ...
- iOS多线程的初步研究1
iOS多线程的初步研究(一) 对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NS ...
- iOS多线程的初步研究(六)
iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...
- iOS多线程的初步研究3
iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...
- iOS多线程的初步研究(一)-- NSThread
对于多线程的开发,iOS系统提供了多种不同的接口,先谈谈iOS多线程最基础方面的使用.产生线程的方式姑且分两类,一类是显式调用,另一类是隐式调用. 一.显示调用的类为NSThread.一般构造NSTh ...
- iOS多线程的初步研究(六)-- NSOperation
iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管理线程的运行,从而更加简洁地实 ...
- iOS多线程的初步研究(五)-- 如何让NSURLConnection在子线程中运行
可以有两个办法让NSURLConnection在子线程中运行,即将NSURLConnection加入到run loop或者NSOperationQueue中去运行. 前面提到可以将NSTimer手动加 ...
- iOS多线程的初步研究(三)-- NSRunLoop
弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run loop可以用于处理异步事件, ...
- iOS多线程的初步研究(九)-- dispatch源
dispatch源(dispatch source)和RunLoop源概念上有些类似的地方,而且使用起来更简单.要很好地理解dispatch源,其实把它看成一种特别的生产消费模式.dispatch源好 ...
随机推荐
- PF_RING 实验
前提:pf_ring.ko 运行在模式2 收包实验: 使用两台机器同时对装PF_RING的机器进行发包,此机器的网卡流量达到14M的效果.如下所示: 上图为PF_RING自 ...
- Java实现多线程邮件发送
利用java多线程技术配合线程池实现多任务邮件发送. 1.基本邮件发送MailSender package hk.buttonwood.ops.email; import java.io.File; ...
- Cygwin ssh服务配置 (SecureCRT连接Cygwin配置)
1.运行ssh-host-config 这里需要注意的是标红部分,输入的用户名或密码要符合计算机的用户名或密码策略(尤其是公司有权限限制的电脑). $ ssh-host-config *** Quer ...
- P1951: [Sdoi2010]古代猪文
呜啊啊啊啊,选错了题,原以为很简单的优化+剪枝就能过结果牵扯到了一堆数论知识.我的错,贴上我的代码(已经尽量优化了) ; var n,g,i,j,ans:longint; tem:int64; fun ...
- 基于.net mvc的校友录(六、codefirst的使用以及班级模块的关键部分实现)
通过EF将新用户存入数据库 这里,探讨一下如何使用EF的code first将数据存入数据库,以及如何对用户的密码进行md5加密与验证.下面是用户登陆的前台代码. @using (Html.Begin ...
- 玩耍Hibernate系列(一)补充--基础知识
基本概述: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得java程序员可以随心所欲的使用对象编程思维来操纵数据库,Hibernate可以应用在任何 ...
- text-overflow 与 word-wrap:设置使用一个省略标记...标示对象内文本的溢出。
text-overflow 与 word-wrap text-overflow用来设置是否使用一个省略标记(...)标示对象内文本的溢出. 语法: 但是text-overflow只是用来说明文字溢出时 ...
- 设计模式 --深入理解javascript
/* 一.单例模式 */ var Universe; (function () { var instance; Universe = function Universe() { if (instanc ...
- MySQL 字符串截取相关函数
MySQL 字符串截取相关函数 在工作中,可能需要将某些字段按某个分割符组成一个字符串作为字段值存取到数据库表中,比如某个任务对应三个结果,分别存储在不同的数据表中,这时可以将这三个不同表的主键按照约 ...
- 显示器VGA视频数据线的问题
一朋友原来有一套PC电脑,后来买了一台新的显示器,新的显示器分辨率为1920X1080,主机接到新的显示器上,分辨率始终无法上到1920X1080,原主机的显示卡驱动已经是最新,还是不行,又重新安装操 ...