RunLoop使用

1、runloop是什么?

    是一个为了保持程序持续运行的do-while死循环。程序循环中,处理APP中的各种事件,像touch、定时器、selector事件,从而保持程序持续运行,没事时休眠,节约CPU资源,提高了程序的性能。

    Do-while:先执行循环语句,然后判断while中表达式真假,若真,继续执行,若假,退出循环。

    原理:线程中的一个循环,循环中不断的检测input source和timer source,就是不断检测输入源和定时源,等待接收待处理事件,接收到事件后,通知线程处理,没有事件,进行休眠。

2、相关类

    RunLoop主要是用NSRunLoop(oc面向对象)和CFRunLoopRef(底层C语言)两个框架,

    其中CFRunLoopRef相关类包括五类:Runloop的对象、RunLoop的运行模式、RunLoop的输入源和事件源、RunLoop的定时器、RunLoop的观察者监听RunLoop状态改变。

  (CFRunLoopRef、CFRunLoopModeRef、CFRunLoopSourceRef、CFRunLoopTimerRef、CFRunLoopObserverRef)。

    一个RunLoop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer。

    RunLoop的运行模式五种:1、default默认模式,2、UITracking界面跟踪模式 3、Common占位模式,主要包含默认和UI界面跟踪模式 4、启动app时初始化runloop的一个mode,app启动后就没用了。5、接受系统事件的内部的mode,但是系统事件触发时会自动用。

    RunLoop的数据源:source0和source1 。source0是非基于port的。只含回调函数指针,不能主动触发事件,不能主动唤醒runloop,主要是用户手动触发事件,像触摸事件等。source1是基于port,通过内核和其他线程通信,接收和分发系统事件,含mach-port和一个回调函数指针,会主动唤醒runloop。

    RunLoop的观察者,7种模式。1、entry进入模式。2、BeforeTimers处理时间源 3、BeforeSources处理输入源  4、BeforeWaiting休眠 5、AfterWaiting 唤醒  6、Exit退出 7、AllActivities监听全部状态改变。

3、RunLoop的处理顺序简介

    1、通知观察者,即将进入循环。2、通知观察者,即将处理定时器。3、通知观察者,即将处理非基于port的数据源source0。4、如果有source1,准备好并等待处理,重新唤醒runloop,从定时器开始处理。5、通知观察者,即将休眠,等待被唤醒。6、通知观察者,即将被唤醒,处理新的未处理事件。(唤醒的方式:1、一个基于 port 的Source1 的事件。2、一个 Timer 到时间了。3、RunLoop 启动时设置的最大超时时间到了。4、被手动唤醒) 7通知观察者,RunLoop结束。

4、RunLoop的应用:

    1、NSTimer定时器。

    2、ImageView显示优化时,当图片加载太多高清图片时,可以开启多个线程和RunLoop处理。

    3、PerformSelector添加线程时会用到,实际是内部创建了一个timer,并添加到当前线程的runloop中。

    4、新增一个常驻线程。(下载文件、后台播放等)让一个子线程不进入消亡状态时,等待其他线程发来事件,处理事件。

    5.自动释放池。加在一个RunLoop上,alloc、new出来的对象,当引用计数器变成0时,会被让入自动释放池中,当runloop没有事件处理时,会将旧的释放池销毁,生成新的释放池,存放待释放对象。

    6、在一个子线程中,长期监听RunLoop状态,然后根据不同状态处理事件时会用。  

RunLoop的问题:

1、runloop是来做什么的?runloop和线程有什么关系?主线程默认开启了runloop么?子线程呢?

    runloop: 字面意思就是跑圈,其实也就是一个循环跑圈,用来处理线程里面的事件和消息。runloop和线程的关系:每个线程如果想继续运行,不被释放,就必须有一个runloop来不停的跑圈,以来处理线程里面的各个事件和消息。主线程默认是开启一个runloop。也就是这个runloop才能保证我们程序正常的运行。子线程是默认没有开始runloop的。

2、runloop的mode是用来做什么的?有几种mode?

    model:是runloop里面的模式,不同的模式下的runloop处理的事件和消息有一定的差别。系统默认注册了5个Mode:(1)kCFRunLoopDefaultMode:App的默认 Mode,通常主线程是在这个 Mode 下运行的。(2)UITrackingRunLoopMode: 界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响。(3)UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用。(4)GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到。(5)kCFRunLoopCommonModes: 这是一个占位的 Mode,没有实际作用。注意iOS 对以上5中model进行了封装NSDefaultRunLoopMode、NSRunLoopCommonModes

3、苹果是如何实现AutoreleasePool的?

    AutoreleasePool作用:缓存池,可以避免我们经常写relase的一种方式。其实就是延迟release,将创建的对象,添加到最近的autoreleasePool中,等到autoreleasePool作用域结束的时候,会将里面所有的对象的引用计数器 - autorelease.


猜你喜欢

转载自blog.csdn.net/pdd_1128/article/details/79915093