美文网首页
iOS之RunLoop

iOS之RunLoop

作者: 柚子_童鞋 | 来源:发表于2017-02-22 20:57 被阅读0次

    RunLoop 是 iOS 和 OS X 开发中非常基础的一个概念,对于iOS系统上的APP来说:有了RunLoop的存在进而保证程序的持续运行。网上的资料太多,但是太多都比较晦涩,于是自己整理一些;

    写在最前:iOS关于RunLoop的学习框架有两套:OC的Foudation框架和C语言的Core Foundation框架;

    在看了源码以及相关资料整理一下笔记:
    Q:线程与RunLoop之间的关系:
    A:一般来讲,每条线程都有唯一的与之对应的RunLoop对象;

    Q:RunLoop在何时被创建?
    A:在程序启动时候会默认创建主线程,与主线程对应的RunLoop在程序启动时候已自动创建并启动;而子线程的RunLoop则需要手动去创建;

    Q:RunLoop在何时被销毁?
    A:主线程的RunLoop不会被销毁,而子线程的RunLoop在子线程内的任务结束时被销毁;

    Q:RunLoop如何创建?
    A:此时要注意,一般的OC语言创建对象是alloc init来创建,RunLoop在源码内部为懒加载设计,当获取到当前的RunLoop为nil,则会自动创建,并且只创建一次。

    Q:如何获取RunLoop对象?
    A:获取主线程的RunLoop对象:[NSRunLoop mainRunLoop];
    获取子线程的RunLoop对象:[NSRunLoop currentRunLoop];

    Q:与RunLoop相关的有哪些类?
    A:五个类(结合下面的图):
    CFRunLoopRef
    CFRunLoopModeRef — 运行模式
    CFRunLoopTimeRef — 定时器
    CFRunLoopSourceRef — 事件
    CFRunLoopObserverRef — 观察者


    下面我们结合这五个类来一一了解:
    CFRunLoopModeRef — 运行模式

    系统提供了五种模式:
    1,kCFRunLoopDefaultMode:系统默认模式,主线程的RunLoop模式;
    2,UITrackingRunLoopMode:界面跟踪Mode,用于跟踪scroview触摸滑动;
    3,UIInitializationRunLoopMode:在刚启动APP时进入的第一种Mode,APP启动后该模式即废弃不再使用;
    4, GSEventReceiveRunLoopMode:接收系统事件的内部Mode;(graphic service内部绘图渲染等)
    5,kCFRunLoopCommonMode:占位模式,并不是真正的Mode

    每次RunLoop启动都要指定一个Mode,此ModeCurrentModeRunLoop可以在多个模式之间切换;如果要切换Mode,只能退出Loop,再次重新指定一个Mode;区别开不同的Source/Timer/Observer,使其彼此互不干扰;


    CFRunLoopTimeRef — 基于时间的触发器;

    其实就是NSTimer,大家对于NSTimer应该都比较熟悉,再次就不做过多解释;


    CFRunLoopSourceRef -- 事件源(输入源)

    在官方文档上,分类如下:

    Port-Based Sources
    Custom Input Sources
    Cocoa perform Selector Sources

    但是在实践过程中我们按照函数调用栈来分:

    Source0:非基于Port的;
    Source1:基于Port的,通过内核和其他线程通信,用来接收、分发系统事件;


    CFRunLoopObserverRef — 观察者模式

    能够监听RunLoop状态的改变;
    可以监听的事件(或者说状态)见官方文档截图:

    kCFRunLoopEntry = (1UL << 0), //即将进入Loop
    kCFRunLoopBeforeTimers = (1UL << 1), //即将处理Timer
    kCFRunLoopBeforeSources = (1UL << 2), //即将处理source
    kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
    kCFRunLoopAfterWaiting = (1UL << 6), //从休眠状态中唤醒
    kCFRunLoopExit = (1UL << 7), //即将退出Loop
    kCFRunLoopAllActivities = 0x0FFFFFFFU //``所有的状态

    以上就是RunLoop的一些概念性的东西,有些枯燥,在接下来我会结合代码和实际场景进行演示,希望能与大家共同学习,共同进步;

    相关文章

      网友评论

          本文标题:iOS之RunLoop

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