一、什么是RunLoop

  1. 从字面意思理解:运行循环、跑圈。
  2. 基本作用:
    • 保持程序(应用)的持续运行。
    • 处理程序(APP)中的各种事件(比如:触摸事件、定时事件、Selector事件等)
    • 节省CPU资源,提高程序的性能:调度CPU,该做事时做事,该休息时休息。
  3. 每个程序中的RunLoop是在Main函数中创建的,实际上是在以下代码中创建的
    int main(int argc, char * argv[]) {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    }

二、RunLoop 对象

  1. iOS中有两套API来访问和使用RunLoop:Foundation(OC,面向对象:NSRunLoop类)、Core Foundation(C,面向对象:CFRunLoop类)
  2. NSRunLoop和CFRunLoop都是代表着RunLoop对象,但是NSRunLoop是基于CFRunLoop的一层OC包装,所以要了解RunLoop的内部结构,需要多研究CFRunLoop层面的API(Core Foundation层面)。

三、RunLoop与线程

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

四、获取RunLoop对象

  1. Foundation框架

        [NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
    [NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
  2. Core Foundation框架
        CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
    CFRunLoopGetMain(); // 获得主线程的RunLoop对象

五、RunLoop 相关类

  1. CFRunLoopRef:RunLoop的对象类。
  2. CFRunLoopModelRef:代表RunLoop的运行模式。
    系统默认注册了5个Model:
    kCFRunLoopDefaultMode: APP的默认Model,通常主线程是在这个Model下运行。
    UITrackingRunLoopMode: 界面跟踪Model,用于Scrollview追踪触摸滑动,保证界面滑动时不受其他Model影响。
    UIInitializationRunLoopModel: 刚启动APP时进入的第一个Model,启动完成后就不再使用。
    GSEventReceiveRunLoopModel: 接受系统事件的内部Model,通常用不到。
    kCFRunLoopCommonModes: 这是一个占位用的Model,不是一种真正的Model。话句话说,是一种标记,这种标记存在以下两种模式中:kCFRunLoopDefaultMode、UITrackingRunLoopMode。
    • 一个RunLoop包含若干个Model,每个Model又包含若干个Source、Timer、Observer。
    • 每次RunLoop启动时,只能指定其中一个Model,这个Model被称作CurrentModel。
    • 如果需要切换Model,只能退出Loop,再重新指定一个Model进入。
  3. CFRunLoopSourceRef:是事件源(输入源)。
    按照官方文档,Source的分类:
    ① Port-Based Source (系统内核中的事件)。
    ② Custom Input Source (自定义事件)。
    ③ Cocoa Perform Selector Source。 按照函数调用栈,Source的分类:
    ① Source0:非基于Port的。
    ② Source1:基于Port的,通过内核和其他线程通信,接收、分发系统事件。
  4. CFRunLoopTimerRef:是基于时间的触发器,基本上说的就是NSTimer,它是受Model影响的。
  5. CFRunLoopObserverRef:是观察者,能够监听RunLoop的状态改变。
    可以监听的时间点有以下几个:
    typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << ), // 即将进入Loop
    kCFRunLoopBeforeTimers = (1UL << ), // 即将处理 Timer
    kCFRunLoopBeforeSources = (1UL << ), // 即将处理 Source
    kCFRunLoopBeforeWaiting = (1UL << ), // 即将进入休眠
    kCFRunLoopAfterWaiting = (1UL << ), // 刚从休眠中唤醒
    kCFRunLoopExit = (1UL << ), // 即将推出Loop
    kCFRunLoopAllActivities = 0x0FFFFFFFU // RunLoop的全部活动
    };
    /******************************举例如下****************************************/
    // 添加observer
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAlloca  torGetDefault(), kCFRunLoopAllActivities, YES, , ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    NSLog(@"---监听到RunLoop的活动状态------%lu", activity);
    });
    // 添加观察者:监听RunLoop的状态
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);  
  6. RunLoop 的运行逻辑理解

六、RunLoop 应用

  1. NSTimer 的使用。
  2. performSelector 的使用。
  3. ImageView的显示。
  4. 常驻子线程。自动释放池(自动释放在进入RunLoop时创建,在RunLoop休眠前(kCFRunLoopBeforeWaiting)释放)。

七、总结

  1. RunLoop浅层了说就是运行循环;深层次的说它内部就是一个do-while循环,在这个循环中不断的处理各种任务(比如:source、timer、observer)。
  2. 一个线程对于一个RunLoop,主线程的RunLoop默认是自动开启的,子线程的RunLoop需要手动去启动(调用RunLoop的run方法)。
  3. RunLoop只能选择一种Model启动,如果当前Model中没有Source(source0、source1)、Timer,那么就会直接退出RunLoop(注意:添加Observer进去无效)。

RunLoop的更多相关文章

  1. RunLoop 总结:RunLoop的应用场景(一)

    参考资料 好的书籍都是值得反复看的,那好的文章,好的资料也值得我们反复看.我们在不同的阶段来相同的文章或资料或书籍都能有不同的收获,那它就是好文章,好书籍,好资料.关于iOS 中的RunLoop资料非 ...

  2. 我的runloop学习笔记

    前言:公司项目终于忙的差不多了,最近比较闲,想起叶大说过的iOS面试三把刀,GCD.runtime.runloop,runtime之前已经总结过了,GCD在另一篇博客里也做了一些小总结,今天准备把ru ...

  3. [tableView reloadData] 和 runloop

    需要[tableView reloadData]后需要立即获取tableview的cell.高度,或者需要滚动tableview,那么,直接在reloadData后执行代码是会有问题的. 断点调试感觉 ...

  4. RunLoop 总结:RunLoop的应用场景(二)

    上一篇讲了使用RunLoop保证子线程的长时间存活,而不是执行完任务后就立刻销毁的应用场景.这一篇就讲述一下RunLoop如何保证NSTimer在视图滑动时,依然能正常运转. 参考资料 好的书籍都是值 ...

  5. iOS多线程-RunLoop简介

    什么是RunLoop? 从字面上来看是运行循环的意思. 内部就是一个do{}while循环,在这个循环里内部不断的处理各种任务(比如:source/timer/Observer) RunLoop的存在 ...

  6. RunLoop(基本操作)

    基本概念 -(void)runTimerInThread { //NSAutoreleasePool,没的用 [NSTimer scheduledTimerWithTimeInterval:1.0 t ...

  7. iOS RunLoop简介

    一.什么是RunLoop? RunLoop是运行循环,每个Cocoa应用程序都由一个处于阻塞状态的do/while循环驱动,当有事件发生时,就把事件分派给合适的监听器,如此反复直到循环停止.处理分派的 ...

  8. 深入理解RunLoop

    网上看的一篇文章,写的真好,我得多看几次好好理解理解 膜拜大神,转载至此便于学习查看. 此处标明原文链接:http://blog.ibireme.com/2015/05/18/runloop/    ...

  9. RunTime&RunLoop初见

    什么是runtime 1> runtime是一套底层的c语言API(包括很多强大实用的c语言类型,c语言函数); 2>实际上,平时我们编写的oc代码,底层都是基于runtime实现的 也就 ...

随机推荐

  1. JHChart 1.1.0 iOS图表工具库中文ReadMe

    JHChart(最新版本1.1.0) 好吧,的确当前的github上已经存有不少的iOS图表工具库,然而,当公司的项目需要图表时,几乎没有哪个第三方能够完全满足我的项目需求.无奈之下,本人不得不花费一 ...

  2. 女生学Web前端优势往往很明显

    学Web前端的女生不算少数,女生学习的成果也往往不比男生差,前端偏向设计.交互和产品方向,需要更加贴合用户,女生心思细腻,对页面细节把控更好,更具美感,对用户心理把握更准,这样的优势往往是男生所不具备 ...

  3. R3.2.2安装

  4. Linux中不同主机建立免登陆

    ssh-keygen -t rsa scp /root/.ssh/id_rsa.pub  root@192.168.0.236:/root/.ssh/authorized_keys cat /root ...

  5. zsh 自动补全导致命令显示重复

    关键字:autocomplete, zsh, backspace, securecrt, xterm, linux console 举个例子: 输入命令ls  然后按TAB补全试试,发现竟然是这样的 ...

  6. javascript 转盘抽奖代码和计数器代码

    要介绍了javascript圆盘抽奖程序实现原理和完整代码例子,需要的朋友可以参考下  看到网页上有不少大转盘抽奖的应用,心血来潮也想弄个.于是找了点资料自己研究...  效果预览: 一.模拟抽奖的实 ...

  7. 如何用 SQL Tuning Advisor (STA) 优化SQL语句

    在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...

  8. Flume(1)使用入门

    一.概述: Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统. 当前Flume有两个版本Flume 0.9X版本的统称Flume-og,Flume1.X ...

  9. 【My Life】写在年末, 我的2013

    [My Life]写在年末, 我的2013 SkySeraph Dec. 30  2013 Email:skyseraph00@163.com 好久没写博客了, 遗忘的历史,遗忘了自我... 岁月拾回 ...

  10. JAVA中MAP值保持顺序不变

    今天在进行JAVA开发过程中,因需要使用MAP来存放数据,同时希望MAP中KEY的顺序与放入顺序保持一致. 在使用HashMap之后,发现KEY的顺序是乱序的,每次打印还不太一样.上网查询资料之后发现 ...