关于 NSTimer 和 NSRunLoop 的一些理解

一:NSTimer和NSRunLoop的关系?

只要出现NSTimer必须要有NSRunLoop,NSTimer必须依赖NSRunLoop才能执行 。NSTimer其实也是一种资源,如果看过多线程编程指引文档的话,我们会发现所有的source如果要起作用,就得加到runloop中去。同理timer这种资源要想起作用,那肯定也需要加到runloop中才会生效喽。如果一个runloop里面不包含任何资源的话,运行该runloop时会立马退出。你可能会说那我们APP的主线程的runloop我们没有往其中添加任何资源,为什么它还好好的运行。我们不添加,不代表框架没有添加,如果有兴趣的话你可以打印一下main thread的runloop,你会发现有很多资源。

二 :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来执行,不需要用addTimer方法。

  1. //关闭 - 永久关闭
  2. [timer invalidate];
  1. //暂时定时器
  2. [myTimer setFireDate:[NSDate distantFuture]];
  1. //开启定时器
  2. [myTimer setFireDate:[NSDate distantPast]];

NSRunLoop与timer有关方法为:

- (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode; //在run loop上注册timer

主线程已经有run loop,所以NSTimer一般在主线程上运行都不必再调用addTimer:。但在非主线程上运行必须配置run loop

三 : NSRunLoop主要方法一览

+ (NSRunLoop *)currentRunLoop; //获得当前线程的run loop

+ (NSRunLoop *)mainRunLoop; //获得主线程的run loop

- (void)run; //进入处理事件循环,如果没有事件则立刻返回。注意:主线程上调用这个方法会导致无法返回(进入无限循环,虽然不会阻塞主线程),因为主线程一般总是会有事件处理。

- (void)runUntilDate:(NSDate *)limitDate; //同run方法,增加超时参数limitDate,避免进入无限循环。使用在UI线程(亦即主线程)上,可以达到暂停的效果。

- (BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate; //等待消息处理,好比在PC终端窗口上等待键盘输入。一旦有合适事件(mode相当于定义了事件的类型)被处理了,则立刻返回;类同run方法,如果没有事件处理也立刻返回;有否事件处理由返回布尔值判断。同样limitDate为超时参数。

- (void)acceptInputForMode:(NSString *)mode beforeDate:(NSDate *)limitDate; //似乎和runMode:差不多(测试过是这种结果,但确定是否有其它特殊情况下的不同),没有BOOL返回值。

官网文档也提到run和runUntilDate:会以NSDefaultRunLoopMode参数调用runMode:来处理事件。

当app运行后,iOS系统已经帮助主线程启动一个run loop,而一般线程则需要手动来启动run loop。

使用run loop的一个好处就是避免线程轮询的开销,run loop在无事件处理时可以自动进入睡眠状态,降低CPU的能耗。

[[NSRunLoop mainRunLoop] run]; //主线程永远等待,但让出主线程时间片

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate distantFuture]]; //等同上面调用

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate date]]; //立即返回

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //主线程等待,但让出主线程时间片,然后过10秒后返回

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; //主线程等待,但让出主线程时间片;有事件到达就返回,比如点击UI等。

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate date]]; //立即返回

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [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];

时间: 2024-10-07 17:24:42

关于 NSTimer 和 NSRunLoop 的一些理解的相关文章

NSRunLoop的进一步理解

iPhone应用开发中关于NSRunLoop的概述是本文要介绍的内容,NSRunLoop是一种更加高明的消息处理模式,他就高明在对消息处理过程进行了更好的抽象和封装,这样才能是的你不用处理一些很琐碎很低层次的具体消息的处理,在NSRunLoop中每一个消息就被打包在input source或者是timer source中了,来看详细内容. 1.什么是NSRunLoop 我们会经常看到这样的代码: - (IBAction)start:(id)sender { pageStillLoading =

iOS多线程的初步研究(四)-- NSTimer

 iOS多线程的初步研究(四)-- NSTimer 原文地址  http://www.cnblogs.com/sunfrog/p/3243230.html 理解run loop后,才能彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的. 先看看NSTimer的两个常用方法: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelec

将NSTimer添加至RunLoop中的两种方法区别

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];          //用NSObject的方法创建一个多线程     [self p

NSTimer的详细用法

NSTimer 详细设置 NSTimer 详细设置1:http://blog.csdn.net/davidsph/article/details/7899483 NSTimer 详细设置2:http://blog.csdn.net/davidsph/article/details/7899731 1 ..... 先说一下我的业务需求,最近在做一个小项目,需要用到定时器的功能,NSTimer类,期间,出现了一些小问题,不过最终通过自己的努力,终于做出来了.我想总结一下,我对NSTimer类的学习和

iOS RunLoop了解和使用

RunLoop 上次讲了runtime,这次是runloop,虽然两者都是run开头的名词术语,但是在OC中,这两个东西压根没啥联系.这篇文章主要讲讲runloop的一些概念和用法.其中包含: 什么runloop runloop是怎么存在的 runloop中包含哪些东西 日常开发中使用到runloop 的场景 一.什么是runloop 一个很容易想到的现象: 当我们将手机解锁进入某个APP之后,如果不操作手机(包括网络请求的行为),手机不会有任何反应,一旦我们进行了操作的时候,手机就会执行响应的

UI基础—— UIScrollView

一.UIScrollView使用的步骤 1.创建UIScrollView 2.将需要展示的内容添加到UIScrollView中 3.设置UIScrollView的滚动范围 (contentSize) 1 @interface ViewController () 2 @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 3 @end 4 // 1.添加两个子控件到UIScrollView中 5 // 一个控件没有设置frame

【OC学习-24】实例:创建一个文件并连续写入10次当前时间——巩固文件操作和熟悉定时器操作

(1)创建一个writeData类,在writeData.h里面: #import <Foundation/Foundation.h> @interface writeData : NSObject -(void)runWrite;//定义一个方法供调用,这个方法是创建并打开一个文件,然后利用定时器每个1秒调用另一个私有方法,这私有方法把当前时间到这个文件夹,但只写10次 @end (2)在writeData.m里面具体实现功能: #import "writeData.h"

编程的有效方法--避免循环引用

1.引起循环引用的原因 1> A拥有B,B拥有C.当C需要销毁时,发现被B拥有,当B需要销毁时,发现被A用有,从而导致内存泄漏.如NSTimer(NSRunloop拥有NSTimer,NSTimer拥有self): 2> A拥有B,B拥有A.如block作为属性时,使用代理时: 2.打破循环引用 打破循环引用的关键在于解除上述的拥有关系: 3.出现循环引用的三种情况 NSTimer 定时器跟Runloop协同工作,Runloop是拥有NSTimer的,同时NSTimer是拥有self的,这就导

关于NSRunLoop和NSTimer的深入理解

一.什么是NSRunLoop NSRunLoop是消息机制的处理模式 NSRunLoop的作用在于有事情做的时候使的当前NSRunLoop的线程工作,没有事情做让当前NSRunLoop的线程休眠 NSTimer默认添加到当前NSRunLoop中,也可以手动制定添加到自己新建的NSRunLoop NSRunLoop就是一直在循环检测,从线程start到线程end,检测inputsource(如点击,双击等操作)同步事件,检测timesource同步事件,检测到输入源会执行处理函数,首先会产生通知,