美文网首页
runloop:运行循环

runloop:运行循环

作者: 就是西柚吖 | 来源:发表于2020-05-22 16:57 被阅读0次

    一,基本知识

    1.作用:

               1).保持程序的持续运行(iOS程序一直活着的原因)

               2).处理APP中的各种事件(触摸事件、timer事件、selector事件)

               3).节约CPU资源,提高程序的性能(有事做事,没事休息)

    2.runloop对象

               1).在iOS开发中有两套API来访问runloop

                    ·Foundation框架【NSRunloop】OC

                    ·Core Foundation框架【CFRunloopRef】C

               2). NSRunloop和CFRunloopRef是等价的,都代表runloop对象,可以相互转换

                   NSRunLoop是基于CFRunLoopRef的一层OC包装

    3.runloop和线程的关系

               1).一个runloop对应着一条唯一的线程。

                      问题:如何让线程不死

                      回答:给这条子线程开一个runloop

               2).runloop的创建:主线程的runloop已经创建好了,子线程的runloop需要手动创建

               3).runloop生命周期:第一次获取时候创建,在线程结束时销毁

    二,runloop对象的创建

    1.foundation框架下创建

                1).  //获取当前线程下的Runloop,懒加载的形式创建

                     NSRunloop *runloop1 =[NSRunloop currentRunloop];

                2) .//获取主线程下的Runloop

                    NSRunloop *runloopMain =[NSRunloop mainRunLoop];

    2.CFRunloopRef框架下创建

               1). CFRunLoopRef runloop2 = CFRunLoopGetCurrent();

               2).CFRunLoopRef runloop2 = CFRunLoopGetMain();

    3.runloop运行原理

     4.Runloop相关的类

          1)CFRunloopRef

          2)CFRunloopModeRef【runloop的运行模式】

          3)CFRunloopTimerRef【Timer事件】 

         4)CFRunloopSourceRef【Runloop要处理的事件源】

         5)CFRunloopObserverRef【Runloop的观察者(监听者)】

         runloop要想跑起来,内部必须有一个mode,mode中必须有source/observer/time,至少要有其中的一个

    5. CFRunloopModeRefRunloop的运行模式】

          runloop每次启动的时候只能指定一个运行模式,切换模式时候必须退出当前mode,再重新进入一个  mode,是为了分割不同组的定时器互不影响

        1)KCFRunloopDefaultMode:APP的默认mode,通常主线程是在这个mode下运行

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

       3)UIInitializationRunLoopMode:在刚启动APP时进入的第一个mode,启动完成之后不再使用

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

       5)kCFRunLoopCommonModes:这是一个占位用的mode,不是一种真正的mode

    6. CFRunloopTimerRefTimer事件】

            1)   NSTimer

        2) GCD定时器

           GCD定时器必须保存起来才能使用

    7.CFRunloopSourceRefRunloop要处理的事件源】

         1)以前的分法

            Port-Based Sources

            Custom Input Sources

            Cocoa Perform Selector Sources

        2)现在的分法

           Source0:非基于Port的(用户触发的时间)

           Source1:基于Port的(通过内核和其他线程相互发送消息)

    8.CFRunloopObserverRef Runloop的观察者(监听者)】

    9.运行逻辑

           每次运行runloop,你线程的runloop会自动处理之前未处理的消息,并通知相关的观察者。

      1)通知观察者runloop已经启动

      2)通知观察者任何即将要开始的定时器

      3)通知观察者任何即将启动的非端口的源 

      4)启动任何准备好的非基于port的Source

      5)如果基于端口的源准备好并处于等待状态,立即启动,并进入步骤9

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

      7)将线程置于休眠直到任一下面的事件发生   

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

              2> 定时器启动

              3> runloop设置的时间已经超时

              4> runloop被显示唤醒

      8) 通知观察者线程将被唤醒

      9) 处理未处理的事件

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

           2>如果输入源启动,传递相应消息

           3>如果runloop被显示唤醒并且没超时,重启runloop,进入步骤2

      10)通知观察者runloop结束

    原文作者1:https://www.cnblogs.com/wsnb/p/4753685.html

    原文作者2:https://juejin.im/post/5c9c231bf265da60cd2b6c5f

    相关文章

      网友评论

          本文标题:runloop:运行循环

          本文链接:https://www.haomeiwen.com/subject/iszqahtx.html