最近处于离职状态,时间也多了起来,但是学习还是不能放松,今天总结一下RunLoop,RunLoop属于iOS系统层的东西,还是比较重要的。

一、什么是RunLoop

字面意思看是跑圈,也可以看作运行循环,我认为RunLoop是个强大的while循环,需要的时候可以将其唤醒工作,不需要的时候可以让其进行休眠节省资源。

那它又有什么作用呢,我总结主要有三点:(1)保持程序的持续运行(2)处理App中的各种事件(比如触摸事件、定时器事件、Selector事件)(3)节省cpu资源,提高程序性能,该做事的时候做事,该休息的时候休息。举个例子,我们程序的入口main函数的UIApplicationMain函数内部久启动了一个RunLoop,所以UIApplicationMain函数一直没有返回,保证了程序的持续运行,默认启动的RunLoop是跟我们主线程相关联的。

二、RunLoop对象

iOS提供了两套API来访问和使用RunLoop:

NSRunLoop(Foundation层)

CFRunLoopRef(Core Foundation层)

三、RunLoop与线程

(1)每条线程都有唯一的一个与之对应的RunLoop对象。

(2)主线程RunLoop已经是创建好的了,子线程的RunLoop需要主动创建。

(3)RunLoop在第一次获取时创建,在线程销毁时销毁,可以将其理解为线程中的变量。

四、RunLoop对象的获取方式

基于Foundation:

    [NSRunLoop currentRunLoop];//或得当前线程的RunLoop对象
[NSRunLoop mainRunLoop];//获得主线程的RunLoop对象

基于Core Foundation:

    CFRunLoopGetCurrent();//或得当前线程的RunLoop对象
CFRunLoopGetMain();//获得主线程的RunLoop对象

五、RunLoop相关类

Core Foundation中关于RunLoop的五个类:

(1)CFRunLoopRef

(2)CFRunLoopModeRef

(3)CFRunLoopSourceRef

(4)CFRunLoopTimerRef

(5)CFRunLoopObserverRef

RunLoop中可以有多个Mode,是RunLoop的重要组成部分,也是RunLoop中不可缺少的部分,可以理解为如果RunLoop中没有Mode那么RunLoop是跑不起来的。所以说它是不可缺少的部分。其中还包括Source,Timer,Observer。Timer是处理定时器的,Observer可以理解为对RunLoop的监听,不如RunLoop的开启或者休眠等等状态,Source表示所要处理的事情,比如说点击某个按钮处理一些事情都属于Source。我觉得有一点很重要,着重提一下,RunLoop的前提是有Mode,Mode的前提是有Source,Timer,Observer。

下面我们对RunLoop中的相关类做个详细介绍:

1.CFRunLoopModeRef

1.1 CFRunLoopModeRef

(1)CFRunLoopModeRef代表着RunLoop的运行模式。

(2)一个RunLoop包含若干个Mode,每个Mode又包含若干个Source,Timer,Observer。

(3)每次RunLoop启动时,只能指定其中一个Mode,这个Mode被称为CurrentMode。

(4)如果需要切换Mode,只能退出RunLoop,再重新指定一个Mode进入,这样做主要为乐分割Source,Timer,Observer让其互不影响。

1.2 系统会默认注册5个模式:

(1)kCFRunLoopDefaultMode:App默认的Mode,通常主线程是在这个Mode下运行的。

(2)UITrackingRunLoopMode:界面跟踪Mode,用于ScrollerView追踪触摸滑动,保证洁面滑动时不受其他Mode影响。

(3)UIInitializationRunLoopMode:在刚启动app时进入的第一个mode,启动完成后就不在使用。

(4)GSEventReceiveRunLoopMode:接受系统事件的内部mode,通常用不到。

(5)kCFRunLoopCommonModes:这是一个占位用的Mode,不是一种真正的mode,可以理解为不是一个确定的模式,既可以支持(1),又可以支持(2)。比如说我们在处理滑动事件定时器问题,这个mode就是很好的解决办法。

2.CFRunLoopSourceRef 事件源(输入源)

(1)Source0:非基于Port的,Port可以理解为我们的内核,比如说自定的一些事件,自己写的函数。

(2) Source1:基于Port的,相当于系统默认调的函数所产生的事件。

一个RunLoop的执行,在线程栈里会有一些我们看不到的函数是系统调用的。

3.CFRunLoopTimerRef

是基于时间的触发器,基本上说的就是NSTimer。

4.CFRunLoopObserverRef

CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变,可以监听的时间点有以下几个:

    typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << ), //即将进入RunLoop
kCFRunLoopBeforeTimers = (1UL << ), //即将处理Timer
kCFRunLoopBeforeSources = (1UL << ),//即将处理Sources
kCFRunLoopBeforeWaiting = (1UL << ),//即将进入休眠
kCFRunLoopAfterWaiting = (1UL << ), //刚从休眠中唤醒
kCFRunLoopExit = (1UL << ), //即将退出RunLoop
kCFRunLoopAllActivities = 0x0FFFFFFFU//监听RunLoop的所有情况
};

比如我们想要在按钮点击之前或者点击之后去做一些事情,我们想要监听到这样的一个状态,就可以使用CFRunLoopObserverRef,NSRunLoop中并没有提供CFRunLoopObserverRef的相关接口,我们要使用只能在Core Foundation中使用。

下面通过实例监测下RunLoop的执行状态:

    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, , ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"activity:%zd",activity);
}); CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
    CFRelease(observer);

打印结果:

-- ::17.268 testRunloop[:] activity:
-- ::17.268 testRunloop[:] activity:
-- ::17.268 testRunloop[:] activity:
-- ::17.270 testRunloop[:] activity:
-- ::17.270 testRunloop[:] activity:
-- ::17.270 testRunloop[:] activity:
-- ::17.270 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.271 testRunloop[:] activity:
-- ::17.276 testRunloop[:] activity:
-- ::17.276 testRunloop[:] activity:
-- ::17.276 testRunloop[:] activity:
-- ::17.277 testRunloop[:] activity:
-- ::17.277 testRunloop[:] activity:
-- ::17.286 testRunloop[:] activity:
-- ::17.286 testRunloop[:] activity:
-- ::17.286 testRunloop[:] activity:
-- ::17.287 testRunloop[:] activity:
-- ::17.287 testRunloop[:] activity:
-- ::17.287 testRunloop[:] activity:
-- ::17.287 testRunloop[:] activity:
-- ::17.743 testRunloop[:] activity:
-- ::17.744 testRunloop[:] activity:
-- ::17.745 testRunloop[:] activity:
-- ::17.745 testRunloop[:] activity:
-- ::18.699 testRunloop[:] activity:
-- ::18.699 testRunloop[:] activity:
-- ::18.700 testRunloop[:] activity:
-- ::18.700 testRunloop[:] activity:
-- ::22.999 testRunloop[:] activity:
-- ::23.000 testRunloop[:] activity:
-- ::23.000 testRunloop[:] activity:
-- ::23.000 testRunloop[:] activity:

现在看这张官方版的逻辑图是不是清晰多了,当然网友的力量是无尽的,下面再给大家展示张网友提供的逻辑图:

总结:RunLoop是与线程相对应的,每个线程都会有一个RunLoop,主线程的RunLoop默认是开启的,不需要我们处理,子线程的RunLoop是关闭的,需要我们自己开启,线程开启的时候RunLoop包含mode,而且必须在某个确定的模式下运行,mode里面的Source,Timer,Observer也需要有,还有包括它们所实现的功能等等。

以上就是对RunLoop的最基本的介绍,希望对大家的学习能有所帮助。

注:此文章为原创,转载请注明出处。

iOS开发RunLoop的更多相关文章

  1. iOS开发RunLoop学习:一:RunLoop简单介绍

    一:RunLoop的简单介绍 #import "ViewController.h" @interface ViewController () @end @implementatio ...

  2. iOS开发RunLoop学习:四:RunLoop的应用和RunLoop的面试题

    一:RunLoop的应用 #import "ViewController.h" @interface ViewController () /** 注释 */ @property ( ...

  3. iOS开发-Runloop详解(简书)

    不知道大家有没有想过这个问题,一个应用开始运行以后放在那里,如果不对它进行任何操作,这个应用就像静止了一样,不会自发的有任何动作发生,但是如果我们点击界面上的一个按钮,这个时候就会有对应的按钮响应事件 ...

  4. iOS开发 - RunLoop理解

    RunLoop概念 运行循环,一个 run loop 就是一个事件处理的循环,用来不停的调度工作以及处理事件 作用 保持程序的持续运行 监听处理App中的各种事件(触摸事件,定时器事件,selecto ...

  5. 玩转iOS开发 - Runloop 具体解释

    Runloop 具体解释

  6. iOS开发RunLoop学习:三:Runloop相关类(source和Observer)

    一:RunLoop相关类: 其中:source0指的是非基于端口por,说白了也就是处理触摸事件,selector事件,source1指的是基于端口的port:是处理系统的一些事件 注意:创建一个Ru ...

  7. iOS开发-- RunLoop的基本概念与例子分析

    看了一下,上一篇貌似5个月前的

  8. iOS开发 - 啰嗦讲解 Runloop

    写在前面的 为什么要了解 RunLoop?如果你想成为一个高级iOS开发工程师,那这是你必须了解的东西,他能帮助你更好的理解底层实现的原理,可以利用它的特性做出一些高效又神奇的功能.RunLoop这个 ...

  9. iOS开发 底层抛析运行循环—— RunLoop

    http://blog.csdn.net/zc639143029/article/details/50012527 一.RunLoop基本概念 概念:程序的运行循环,通俗的来说就是跑圈. 1. 基本作 ...

随机推荐

  1. 深圳尚学堂:Web程序员应该会的知识

    互联网的行业里涌入了很多的程序员, 都在为互联网的发展添砖加瓦.程序员可以分为很多种,像Unix程序员.Windows程序员,或是C++程序员.Delphi程序员,等等.今天我们谈谈Web程序员,一名 ...

  2. [CSS3] 学习笔记-CSS选择器

    CSS3中,选择器的分类很多,有元素选择器.类选择器.ID选择器.属性选择器.后代选择器.子元素选择器.相邻兄弟选择器. 1.最常见的选择器就是元素选择器,文档的元素就是最基本的选择器,例如,h1{} ...

  3. Ubuntu 制作U盘启动盘

    部门需要一台Linux系统远程共享服务器,需要一个启动盘安装.但是由于公司windows 系统都安装了保安软件,而且软件的使用也是有限制的.所以不能使用UltraISO 这类软件制作U盘启动盘.还好部 ...

  4. Yii框架中的form表单

    <?php//引入命名空间use yii\helpers\Html;?><?php //表单:Html::beginForm(提交地址,提交方法,属性数组);?><?=H ...

  5. 【前端】:HTML

    前言: 最近开始学前端了,这篇博客主要介绍html的一些主要标签,写完这篇博客,我会用刚学的html做一个简单的登陆界面~~ 一.HTML介绍 HTML(Hyper Text Mark-up Lang ...

  6. foreach和for循环的区别

    for循环 for循环,通过下标,对循环中的代码反复执行,功能强大,可以通过index取得元素.在处理比较复杂的处理的时候较为方便. foreach循环 foreach,从头到尾,对于集合中的对象遍历 ...

  7. windows下vue+webpack前端开发环境搭建及nginx部署

    一.开发环境搭建 1.前端框架一般都依赖nodejs,我们首先要安装node.js.请参考http://www.cnblogs.com/wuac/p/6381819.html. 2.由于许多npm的源 ...

  8. 【android开发笔记】为Button的背景图片添加边框式样式效果

    现在做的项目遇到一个问题,设计给过来的图片只有一种状态,但是实现的需求是要求有两个状态,另一种选状态为图片背景加边框.如图: 刚开使用使用ImageView ,ImageViewButton 效果不是 ...

  9. CLOSE_WAIT TIME_WAIT

    TCP状态转移要点    TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放.网络服务器程序要同时 ...

  10. AR入门系列-在vuforia官网的使用-01-史上最详细AR入门教程

    使用高通的vuforiaSDK 网址:https://developer.vuforia.com/ 我们想要使用vuforia首先得注册一个账号 网站会发送邮件给你的邮箱 点击验证链接,验证邮箱 出现 ...