将NSTimer加入至RunLoop中的两种方法差别
-
(BOOL)application:(UIApplication
*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window
= [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; //用NSObject的方法创建一个多线程 [self
performSelectorInBackground:@selector(multiThread) withObject:nil]; self.window.backgroundColor
= [UIColor whiteColor]; [self.window
makeKeyAndVisible]; return
YES;}-
(void)multiThread{ NSAutoreleasePool
*pool = [[NSAutoreleasePool alloc] init]; if
(![NSThread isMainThread]) { //
第1种方式 //此种方式创建的timer已经加入至runloop中//
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerAction) userInfo:nil repeats:YES]; //保持线程为活动状态,才干保证定时器运行//
[[NSRunLoop currentRunLoop] run];//已经将nstimer加入到NSRunloop中了 //第2种方式 //此种方式创建的timer没有加入至runloop中 NSTimer
*timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(timerAction) userInfo:nil repeats:YES]; //将定时器加入到runloop中 [[NSRunLoop
currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; [[NSRunLoop
currentRunLoop] run]; NSLog(@"多线程结束"); } [pool
release];}-
(void)timerAction{ //定时器也是在子线程中运行的 if
(![NSThread isMainThread]) { NSLog(@"定时器"); }}
理解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];
大家能够參看博文 p=209" style="color:rgb(29,88,209); text-decoration:none">http://bluevt.org/? p=209
曾经博文中提到延迟调用的方法,事实上就是在当前线程的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;
将NSTimer加入至RunLoop中的两种方法差别的更多相关文章
- javascript原型继承中的两种方法对比
在实际的项目中,我们通常都是用构造函数来创建一个对象,再将一些常用的方法添加到其原型对象上.最后要么直接实例化该对象,要么将它作为父类,再申明一个对象,继承该父类. 而在继承的时候有两种常用方式,今天 ...
- C#把某个数组的一部分复制到另一个数组中的两种方法:Buffer.BlockCopy和Array.Copy
static void Main(string[] args) { , , , , , }; ;//目标数组大小 int int_size = sizeof(int);//用于获取值类型的字节大小. ...
- Js类的静态方法与实例方法区分以及jQuery如何拓展两种方法
上学时C#老师讲到对象有两类方法,静态方法(Static)和实例方法(非Static),当时不理解静态是为何意,只是强记. 后来从事前端工作,一直在对类(即对象,Js中严格来说没有类的定义,虽众所周知 ...
- .net中创建xml文件的两种方法
.net中创建xml文件的两种方法 方法1:根据xml结构一步一步构建xml文档,保存文件(动态方式) 方法2:直接加载xml结构,保存文件(固定方式) 方法1:动态创建xml文档 根据传递的值,构建 ...
- Redis中持久化的两种方法详解
Redis提供了两种不同的持久化方法来将数据存储到硬盘里面.一种方法叫快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里;另一种方法教只追加文件(append-only f ...
- 【转】oracle 中随机取一条记录的两种方法
oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COU ...
- MySQL中的两种临时表
MySQL中的两种临时表 伯乐在线2016-07-06 05:16:52阅读(4556)评论(3) 声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场.举报 ...
- 在shell script中进行数值运算的两种方法
方法1:使用"$((计算式))"的方式进行数值运算,不需要使用declare命令显示声明数值型变量来存储计算结果: 方法2:使用declare命令配合"-i"选 ...
- ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法
ORACLE 查询一个数据表后通过遍历再插入另一个表中的两种写法 语法 第一种: 通过使用Oracle语句块 --指定文档所有部门都能查看 declare cursor TABLE_DEPT and ...
随机推荐
- 紫书 例题 10-6 UVa 1635 (二项式定理+唯一分解定理)
首先可以发现按照题目的算法最后得出来是一个杨辉三角 如果ai的系数是m的倍数,那么i即为答案 因为这个系数可能很大,而我们只需要判断倍数 所以我们就把m分解质因数,然后判断每一个系数 的质因数的幂是不 ...
- Redis报错 : (error) NOAUTH Authentication required.
原文:Redis报错 : (error) NOAUTH Authentication required. 这个错误是因为没有用密码登陆认证 , 先输入密码试试 . 127.0.0.1:6379> ...
- 洛谷——P1019 单词接龙(NOIP2000 T3)
https://www.luogu.org/problem/show?pid=1019#sub 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, ...
- 在iPad iOS8环境下打开相冊或者拍照
在iPad下打开相冊或者拍照,假设使用 UIImagePickerController 打开相冊或者拍照,那必需要用到 UIPopoverController 去打开. UIPopoverContro ...
- CODE ---代码助手 (保存代码、搜代码、生成网页、自由界面)
四大功能 1 保存代码 2 搜索代码 3 生成网页 4 自由界面 www.gudianxiaoshuo.com
- 分析一下jquery中的ajax操作
在web前端开发中,ajax是很重要的一项技术,用原生写起来很是麻烦,需要一大堆js代码,而到了jq里就被精简了许多,一起来看看: jquery中的ajax分为三种方式: 1.$.get(),get方 ...
- Vsftp问题及解决办法汇总(持续增加中)
1.VsFTP出现500 OOPS: cannot change directory的解决办法 在安装完vsftp服务后登陆时可能遇到cannot change directory后面是登陆者的目录的 ...
- POJ2823 单调队列
POJ2823 http://poj.org/problem?id=2823 最基础的单调队列,说是数据结构,其实就是一种更新数组数据的方法. 之前还准备用deque,超时了,直接head,tail快 ...
- Lambda表达式相当于一个函数
看来你对Lambda完全不懂.Lambda表达式相当于一个函数. 比如model => model.Name相当于string 一个函数(Model的类型 model) { return ...
- 安装oracle常见问题分析
1,之前已经安装过软件,卸载不完全 /tmp/.oracle /tmp/ora* /var/tmp/ora* /etc/ora* 2,安装介质权限或者本身就有问题 3,oracle用户 $/HOME/ ...