美文网首页
iOS 中Runloop

iOS 中Runloop

作者: 代码之路 | 来源:发表于2019-12-29 16:40 被阅读0次

    Runloop 字面理解为运行循环

    作用:
    1,保持程序的持续运行。
    2,处理程序中的各种事件,比如触摸事件,定时器事件。Selector方法。
    3,节省CPU资源,提高程序性能。该做事时做事,该休息时休息(Runloop的状态)

    iOS中有两套API访问Runloop
    1,Foundation框架
    NSRunloop
    2,Core Foundation框架
    CFRunloopRef

    NSRunloop是基于CFRunloopRef的封装

    一,runloop与线程的关系
    1,每条线程都有唯一的一个与之对应的runloop
    2,主线程的runloop已经自动创建好了,子线程的runloop需要主动创建。
    3,runloop在第一次获取时创建,在线程结束时销毁。

    二,CFRunloopModeRef
    CFRunloopModeRef代表Runloop的运行模式
    1,一个Runloop包含多个运行模式Mode,每个Mode又包含若干个Source/Timer/Observer。
    2,每次Runloop启动时只能启动一个mode,称之为currentmode,可通过此方法获取。
    3,如果要切换mode,只能先退出loop,再重新指定一个Mode进入。

    系统默认为我们注册了5种运行模式,这里只介绍公开暴露出来的两种

    NSDefaultRunLoopMode 默认Mode,通常主线程运行模式。
    NSEventTrackingRunLoopMode 界面跟踪Mode,ScrollView追踪滑动触摸,保证界面滑动时不受其他Mode影响。
    NSRunLoopCommonModes 标签,被标记的对象可以运行在被标签标记的模式下,随着模式的切换而切换,比如NSTimer。

    iOS 中公开暴露出来的只有 NSDefaultRunLoopMode 和 NSRunLoopCommonModes。 NSRunLoopCommonModes 实际上是一个 Mode 的集合,默认包括 NSDefaultRunLoopMode 和 NSEventTrackingRunLoopMode(注意:并不是说Runloop会运行在kCFRunLoopCommonModes这种模式下,而是相当于分别注册了 NSDefaultRunLoopMode和 UITrackingRunLoopMode。当然你也可以通过调用CFRunLoopAddCommonMode()方法将自定义Mode放到 kCFRunLoopCommonModes组合)。

    三,CFRunLoopSourceRef
    以前分类:
    1,Port
    2,Custom,Input Source
    3,performselector
    现在:
    1,Source0:
    非基于port的,用户主动触发的,如触摸等
    2,Source1:
    基于Port的,基于内核和其他线程相互发送消息。

    四,CFRunLoopObserverRef
    CFRunLoopObserver是观察者,可以观察RunLoop的各种状态,并抛出回调。

    struct __CFRunLoopObserver {
        CFRuntimeBase _base;
        pthread_mutex_t _lock;
        CFRunLoopRef _runLoop;
        CFIndex _rlCount;
        CFOptionFlags _activities;      /* immutable */
        CFIndex _order;         /* immutable */
        CFRunLoopObserverCallBack _callout; /* immutable */
        CFRunLoopObserverContext _context;  /* immutable, except invalidation */
    };
    

    CFRunLoopObserver可以观察的状态有如下6种:

    /* Run Loop Observer Activities */
    typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
        kCFRunLoopEntry = (1UL << 0), //即将进入run loop
        kCFRunLoopBeforeTimers = (1UL << 1), //即将处理timer
        kCFRunLoopBeforeSources = (1UL << 2),//即将处理source
        kCFRunLoopBeforeWaiting = (1UL << 5),//即将进入休眠
        kCFRunLoopAfterWaiting = (1UL << 6),//被唤醒但是还没开始处理事件
        kCFRunLoopExit = (1UL << 7),//run loop已经退出
        kCFRunLoopAllActivities = 0x0FFFFFFFU
    };
    
    什么是Runloop?

    字面意思是一个运行循环,其实内部是一个do while 循环,在处理各种事件,timer,source,Observer。
    一个线程对应一个Runloop。主线程自动启动,子线程需要手动启动,调用Run方法。
    Runloop只能选择一个模式启动,更改模式需要先退出再进入新模式。如果Model没有任何timer。source,那么直接退出runloop。

    自动释放池什么时候释放?

    根据Observer观察的Runloop状态释放,runloop退出。

    五,Runloop应用
    1,NSTimer
    定时器设置为CommonMode更精准
    2,ImageVIew显示
    将图片的显示设置在UITracking模式,可以保证在列表滑动的时候依然能够加载视图。
    3,PerformSeletor
    4,常驻线程
    创建一个Runloop在子线程一直运行,保证线程在后台常驻(AFNetworking源码)。

    子线程的Runloop需要手动调用,然后添加一个Source或者Timer事件,再调用Run方法。

    5,自动释放池
    Runloop内部会自动创建一个自动释放池,开始的时候创建,等到合适的时机再释放,通过观察Runloop状态来进行。

    6,通过对Runloop添加Observer来做一些事情
    (1),比如监听点击事件,当runloop处理点击事件时候可以统一做一些事情。
    (2),也可以通过对Runloop状态的观察来检测系统卡顿,当长时间处于一个模式不变就是出现了卡顿。

    //创建子线程监控
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //子线程开启一个持续的 loop 用来进行监控
        while (YES) {
            long semaphoreWait = dispatch_semaphore_wait(dispatchSemaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC));
            if (semaphoreWait != 0) {
                if (!runLoopObserver) {
                    timeoutCount = 0;
                    dispatchSemaphore = 0;
                    runLoopActivity = 0;
                    return;
                }
                //BeforeSources 和 AfterWaiting 这两个状态能够检测到是否卡顿
                if (runLoopActivity == kCFRunLoopBeforeSources || runLoopActivity == kCFRunLoopAfterWaiting) {
                    //将堆栈信息上报服务器的代码放到这里
                } //end activity
            }// end semaphore wait
            timeoutCount = 0;
        }// end while
    });
    
    

    相关文章

      网友评论

          本文标题:iOS 中Runloop

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