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源好 ...
随机推荐
- GraphLab面向机器学习的并行框架『针对图数据处理模型』
最近在做文本处理知识的梳理,关注了CMU提出的GraphLab开源分布式计算系统 这是关于GraphLab的PPT:Distributed GraphLab『 http://cheng-qihang- ...
- memcached 简介
最近,想看看开源的东西,正好在网上看到了memcached这个服务器,就简单学了学.做个笔记! 1.memcached 介绍 memcached我原本以为是一款数据库软件,但详细了解才发现,准确的是一 ...
- Oracle Imp and Exp (导入和导出) 数据 工具使用
Oracle 提供两个工具imp.exe 和exp.exe分别用于导入和导出数据.这两个工具位于Oracle_home/bin目录下. 导入数据exp 1 将数据库ATSTestDB完全导出,用户名s ...
- 调试mvc 源码【转:http://www.cnblogs.com/wucj/archive/2013/06/09/3128698.html】
最近在研究asp.net mvc的源码,于是在想,既然提供了源码,那我们如何进入源码调试了?在网上找了一些调试的方法,试了几个都不行,于是折腾了一上午,终于弄出来了,下面看看我的操作步骤. 一:准 ...
- [转]分布式文件系统FastDFS架构剖析
[转]分布式文件系统FastDFS架构剖析 http://www.programmer.com.cn/4380/ 文/余庆 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实 ...
- C++ 类的前置声明
http://www.2cto.com/kf/201311/260705.html 今天在研究C++”接口与实现分离“的时候遇到了一个问题,看似很小,然后背后的东西确值得让人深思!感觉在学习的过 ...
- Android实现入门界面布局
Android实现入门界面布局 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 代码实现 首先是常量的定义,安卓中固定字符串应该定义在常量中. stri ...
- easyui中jquery重复引用问题(tab内存泄露问题)
今天认真测试了下easyui的一些兼容性问题,发现在ie9 ie10 首次加载的时候,会出现如下bug.如图所示: 认真看了下,我估计是脚本重复引用的问题,我用的iframe框架的模式.登陆系统后,桌 ...
- 在数据表中添加一个字段的SQL语句怎么写
如果要在数据表中添加一个字段,应该如何表示呢?下面就为您介绍表添加字段的SQL语句的写法,希望可以让您对SQL语句有更深的认识. 通用式: alter table [表名] add [字段名] 字 ...
- [shell基础]——I/O重定向
文件标识符(FD) 1. Linux使用文件标识符(FD)来标识一个进程正在访问的特定文件 2. 当打开一个文件或创建一个文件时,Linux将返回一个文件标识符供其他操作引用 3. 文件标识符是一个小 ...