RunLoop是一个对象,用于管理需要处理的事件和消息。
一个runloop就是一个事件处理循环,用来不停的调度工作以及处理输入事件。目的是让线程在有工作的时候忙于工作,没工作的时候处于休眠状态。
runloop是一个do while死循环。循环中一直进行的逻辑是:“接受消息->等待->处理”,直到循环结束(比如quit消息)
Foundation框架的NSRunLoop,提供了面向对象的 API,但是这些 API 不是线程安全的。
Core Foundation框架的CFRunloopRef,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。
1.runloop和线程是一一对应的。
每条线程都有唯一一个和他对应的RunLoop对象,二者是利用字典来存储,key是线程,Value是该线程对应的Runloop
2.ios不允许直接创建RunLoop,只允许获取runloop对象。而且RunLoop是在第一次获取时创建,在线程结束时销毁
3.主线程的Runloop系统已自动创建,并开启
4.子线程默认没有开启RunLoop,需主动获取,子线程常驻的时候需要开启runloop
[NSRunLoop currentRunLoop]; 获得当前线程的 RunLoop对象 [NSRunLoop mainRunLoop]; 获得主线程的RunLoop对象
首先在保存线程和runloop的字典中以线程为key查找所需runloop,如果有则直接返回。如果无则创建一个runloop,并保存到字典中,然后返回这个runloop。说明了runloop和线程是一一对应关系,也说明是懒加载的创建模式,即需要时才创建。
Runloop对象中包含多个model。每一个model包含若干个source, observer,timer
Source是事件源,比如触摸事件,输入事件
Observer是观察者,监听RunLoop的状态
Timers:计时器
source事件(包括Source0事件,Source1事件)
Observer事件(指runloop中状态变化时进行通知)
Timer事件
其他(Block事件,Main_Dispatch_Queue事件)
mode 分类 default. tracking, init, eventReceive, common
NSDefaultRunLoopMode:app默认mode。通常⽤用于主线程。
UITrackingRunLoopMode:界⾯面跟踪model,⽤用于scrollview追踪触摸互动。
kCFRunLoopCommonModes = NSDefaultRunLoopMode + UITrackingRunLoopMode
UIInitializationRunLoopMode:在app刚启动的进⼊入的第⼀个model,启动后就不再使⽤
GSEventReceiveRunLoopMode:接收系统事件内部mode,通常⽤用不不到
1.RunLoop启动时只能选择其中一个Mode作为currentMode
2.如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入。,目的是分开各个mode,免其相互影响
3.如果Mode里没有sources0/sources1/Timer/observer,RunLoop会立马退出
1.保持程序的持续运行
2.处理app中的各种事件:比如触摸事件、定时器事件.其他系统事件
3.节省CPU资源,提高程序性能,有事情就做事情,没事情就休息
1、为当前线程创建一个runloop
2、向runloop中添加Port/Source等维持RunLoop的事件循环(注意:如果runloop的mode中一个item都没有,runloop会退出的) 3、启动该runloop
1.在oc中runloop实际是一个用来管理需要处理的事件和消息的对象。
一个runloop就是一个事件处理的循环,用来不停的调度工作以及处理输入事件, 而使用runloop的目的是让线程在有工作的时候忙于工作,而在没工作的时候出于休眠状态。
2.runtime是一种机制,又叫运行时,是指将一些决定从编译期推迟到代码运行期来处理,runtime底层由c语言实现
在oc中所有的一切都是对象,所以runtime机制就是说;只有在运行时才能真正确定对象的相关信息,故我们利用runtime机制可以在代码运行时获取并修改类的相关信息,比如获取类的方法列表,属性列表,添加方法.属性等。
可以把刷新的操作放在主线程上并将RunLoop设置为NSDefaultRunLoop的模式上即可,这样就会等用户不在滑动,并且手指离开的时候才执行刷新操作了 因为滑动时主现场的runloop为UITrackingRunLoopMode,不滑动时为NSDefaultRunLoopMode。
就是因为UIApplicationMain内部默认开启了一个runloop,并且执行了一段无限循环的代码,(注意这里的无限循环,不是简单的for或者while循环),因为一直在无限循环里,所以这个函数永远不会被返回,而是不断的接收消息/事件以及等待休眠,所以程序运行之后会保持运行状态不会退出
- timerWithTimeInterval;创建的timer不会自动添加到当前线程的runloop中,需要手动加入
- scheduledTimerWithTimeInterval 创建的timer会自动添加到当前线程的runloop中。
timer在主线程时
存在scrollview需要指定model为track(UITrackingRunLoopMode)或者common(NSRunLoopCommonModes)
timer在子线程,加入runloop然后启动即可
存在scrollview。在点击UIScorllview的区域时,mode是UITrackingRunLoopMode, 但若定时器器的model是 NSDefaultRunLoopMode会停⽌止工作。
在第⼀一次获取时创建,在线程结束时销毁
通过source1捕捉系统事件,然后打包成source0这个系统触摸事件分发给app
因为主线程会默认启动runloop,但子线程不会自动启动runloop,故runloop并不是由系统自动控制的.
就是do while死循环。这种机制的关键点就是如何管理事件/消息。比如;如何让在没有消息的时候线程休眠来避免资源占用,和在有消息是即时处理消息。runloop就是对它的优化。本质是一样的。
1.进入runloop循环
2.即将处理time事件
3.即将处理source事件
4.即将休眠
5.结束休眠