zoukankan      html  css  js  c++  java
  • 理解RunLoop

    一、什么是RunLoop?

    从字面意思上来看,RunLoop就是运行循环,跑圈的意思。

    我们都知道,一般来说一个线程执行一次任务之后便会退出,在iOS中,如果主线程只执行一次便退出的话也就意味着程序的停止。那么它是怎样做到让主线程保持不死,让程序一直运行的呢?答案就是RunLoop了。

    打个比方:

    如果没有RunLoop,程序在第三行后便结束了。

    所以,RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行上面 Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 "接受消息->等待->处理" 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。

    二、main函数中的RunLoop

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }

    UIApplicationMain函数内部就启动了一个RunLoop,所以UIApplicationMain一直没有返回,保持了程序的一直运行,这个默认启动的RunLoop是和主线程相关联的

    三、RunLoop与线程

    1.每条线程都有唯一的一个与之对应的RunLoop对象,实现内部是一个全局的字典,key->线程名 value->runloop

    2.主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建

    3.RunLoop在第一次获取时创建,在线程结束时销毁

    四、RunLoop相关类

    Core Foundation中关于RunLoop的5个类

    CFRunLoopRef

    CFRunLoopModeRef

    CFRunLoopSourceRef

    CFRunLoopTimerRef

    CFRunLoopObserverRef
    a.CFRunLoopModeRef:
    1.CFRunLoopModeRef代表RunLoop的运行模式
    2.一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer
    3.每次RunLoop启动时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode
    4.如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入,这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响
    5.系统默认注册了5个Mode:
    NSDefaultRunLoopMode:App的默认Mode,通常主线程是在这个Mode下运行
    UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
    UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
    GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
    NSRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
    b.CFRunLoopTimerRef
    1.CFRunLoopTimerRef是基于时间的触发器
    2.CFRunLoopTimerRef基本上说的就是NSTimer,它受RunLoop的Mode影响
    3.GCD的定时器不受RunLoop的Mode影响
    c.CFRunLoopSourceRef
    CFRunLoopSourceRef是事件源(输入源)
    按照官方文档,Source的分类
    Port-Based Sources

    Custom Input Sources

    Cocoa Perform Selector Sources

     按照函数调用栈,Source的分类

    Source0:非基于Port的

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


    d.CFRunLoopObserverRef

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

     

    五、RunLoop应用

    NSTimer:

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];

    1.调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode

    2.定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作

    3.标记为common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode

    4.runloop Mode里如果没有timer/source/observer 不会开启成功

    ImageView显示
    PerformSelector
    常驻线程
    自动释放池
  • 相关阅读:
    iOS 基础复习
    iOS项目立项
    Cocos2d-JS项目之四:UI界面的优化
    Cocos2d-JS项目之三:使用合图
    Cocos2d-JS项目之二:studio基础控件的使用
    Cocos2d-JS项目之一:环境(IDE 运行js-tests、IDE 和 studio 统一工程)
    字节对齐导致的iOS EXC_ARM_DA_ALIGN崩溃
    cocos2dx 2.x 骨骼动画优化
    Cocos2dx 把 glview 渲染到 Qt 控件上(Mac 环境)
    [leetcode 周赛 160] 1240 铺瓷砖
  • 原文地址:https://www.cnblogs.com/tmacforever/p/5207616.html
Copyright © 2011-2022 走看看