Runloop

1.什么是Runloop

  • 1.从字面意思看,就是一个运行循环.内部是一个do..while循环.循环内部处理各种任务(Sources,Timer,Observer)

  • 2.基本作用:

    • 保持程序的持续运行

    • 处理app中的各种事件(比如触摸事件,定时器事件,selector事件)

    • 节省cpu资源,提高程序性能:该做事时做事,该休息时休息

  • 3.Runloop对象:NSRunLoop 和 CFRunLoopRef

Runloop 消息源 :输入源+定时源

  • 1.创建源

  • 2.加入线程的消息循环并指定模式

  • 3.没有事件就休眠

2.Runloop应用

  • 1.NSTimer

  • 2.ImageView

  • 3.PerformSelector

  • 4.常驻线程

  • 5.自动释放池:什么时候释放?在runloop释放之前释放,自动释放池通过observer对runloop有一个监听,一旦监听到runloop进入休眠,就释放自动释放池

3.Runloop与线程

  • 每条线程都有唯一与之对应的Runloop对象,以键值对形式保存在字典中

  • 主线程的runloop默认开启,子线程的runloop需要手动开启,,Runloop只能选择一个模式启动,开启之后如果要一直运行,需要添加一个port或者加一个timer.

//让子线程的runLoop一直运行的方法
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addport:[NSPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
  • 子线程开启runloop如何能关闭?开启和关闭都必须使用C函数.

  • 线程刚创建时并没有Runloop,Runloop在第一次获取时创建,在线程结束时销毁,只能在一个线程的内部获取其Runloop(主线程除外)

4.获取RunLoop对象

  • 1.Foundation

[NSRunLoop currentRunLoop];
[NSRunLoop mainRunLoop];
  • 2.Core Foundation

CFRunLoopGetCurrent();

CFRunLoopGetMain();

5.RunLoop相关类(对外接口)

  • 1.CFRunLoopRef:

  • 2.CFRunLoopModeRef:

    • 1.代表RunLoop的运行模式

    • 2.一个RunLoop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer

    • 3.每次RunLoop启动时,只能指定其中一个Mode,这个Mode被称作CurentMode

    • 4.如果需要切换Mode,只能退出Loop.重新指定一个Mode进入

    • 5.这样做主要是为了分割开不同组的Source/Timer/Observer

    • 6.系统默认注册了5个Mode:

      • kCFRunLoopDefaultMode:默认模式,通常主线程在该模式下运行

      • UITrackingRunLoopMode:界面跟踪Mode,用于scrollView追踪触摸滑动,保证界面滑动时不受其他影响

      • UIInitializationRunLoopMode:在app刚启动时进入的第一个MOde,启动完成后就不在使用

      • GSEventReceiveRunLoopMode:接收系统事件的内部Mode,通常用不到

      • kCFRunLoopCommonModes:一个占位用的Mode,不是一种真正的Mode,就是一个多个mOde的集合

  • 3.CFRunLoopSourceRef

    • CFRunloopSourceRef 是事件源(输入源)

    • 以前的分法:Port_Based Sources,Custom Input Sources,Cocoa Perform Selector Sources

    • 现在的分法:

      • Sources0---非基于Port的

      • Sources1---基于Port的

  • 4.CFRunLoopTimerRef

    • 是一个基于时间的触发器,基本上说的就是NSTimer

  • 5.CFRunLoopObserverRef

    • 是观察者,能够监听RunLoop的状态的改变

    • 可以监听到的时间点有以下几个:

RunLoop处理逻辑-官方版

  • RunLoop的事件队列:每次运行RunLoop,线程的RunLOOP都会自动处理之前未处理的信息,并通知先关的观察者.具体顺序如下:

  • 1.通知观察者runloop已经启动

  • 2.通知观察者任何即将要启动的定时器

  • 3.通知观察者任何即将启动的非基于端口的源

  • 4.启动任何准备好的非基于端口的源

  • 5.如果任何基于端口的源准备好并处于等待状态.立即启动;并进入步骤9.

  • 6.通知观察者线程进入休眠

  • 7.将线程置于休眠,直到下面任一事件的发生:

    • 某一事件到达基于端口的源

    • 定时器启动

    • RunLoop设置的时间已经超时

    • runloop被显示唤醒

  • 8.通知观察者线程被唤醒

  • 9.处理未处理的事件

    • 如果用户定义的定时器启动,处理定时器事件并重启runloop.进入步骤2

    • 如果输入源启动,传递相应的消息

    • 如果runloop被显示唤醒

  • 10.通知观察者runloop结束




你可能感兴趣的:(OC语言)