RunLoop

作者: mengyingguo | 来源:发表于2017-09-01 10:02 被阅读0次

    参考:http://www.cnblogs.com/superYou/p/4645168.html

    runloop面试题

    1.什么是RunLoop?

    从字面意思看:运行循环、跑圈

    其实它内部就是do-while循环,在这个循环内部不断地处理各种任务(比如Source、Timer、Observer)

    一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop得手动启动(调用run方法)

    RunLoop只能选择一个Model启动,如果当期Model中没有任何Source(Source0、Source1)、Timer,那么久直接退出RunLoop

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

    通过Observer监听RunLoop的状态

    3.在开发中如何使用RunLoop?什么应用场景?

    开启一个常驻线程(让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件)例如:在子线程开启一个定时器;在子线程进行一些长期监控

    可以控制定时器在特定模式下执行

    可以让某些事件行为在特定模式下执行

    可以添加Observe监听RunLoop的状态,比如点击事件的处理(在所有点击事件之前做一些事情)

    1.Runloop基础知识

    - 1.1 字面意思

    a 运行循环

    b 跑圈

    - 1.2 基本作用(作用重大)

    a 保持程序的持续运行(ios程序为什么能一直活着不会死)

    b 处理app中的各种事件(比如触摸事件、定时器事件【NSTimer】、selector事件【选择器·performSelector···】)

    c 节省CPU资源,提高程序性能,有事情就做事情,没事情就休息

    - 1.3 重要说明

    (1)如果没有Runloop,那么程序一启动就会退出,什么事情都做不了。

    (2)如果有了Runloop,那么相当于在内部有一个死循环,能够保证程序的持续运行

    (2)main函数中的Runloop

    a 在UIApplication函数内部就启动了一个Runloop

    该函数返回一个int类型的值

    b 这个默认启动的Runloop是跟主线程相关联的

    - 1.4 Runloop对象

    (1)在iOS开发中有两套api来访问Runloop

    a.foundation框架【NSRunloop】

    b.core foundation框架【CFRunloopRef】

    (2)NSRunLoop和CFRunLoopRef都代表着RunLoop对象,它们是等价的,可以互相转换

    (3)NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)

    - 1.5 Runloop参考资料

    ```objc

    (1)苹果官方文档

    https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

    (2)CFRunLoopRef开源代码下载地址:

    http://opensource.apple.com/source/CF/CF-1151.16/

    ```

    - 1.6 Runloop与线程

    1.Runloop和线程的关系:一个Runloop对应着一条唯一的线程

    问题:如何让子线程不死

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

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

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

    - 1.7 获得Runloop对象

    ```objc

    1.获得当前Runloop对象

    //01 NSRunloop

    NSRunLoop * runloop1 = [NSRunLoop currentRunLoop];

    //02 CFRunLoopRef

    CFRunLoopRef runloop2 =   CFRunLoopGetCurrent();

    2.拿到当前应用程序的主Runloop(主线程对应的Runloop)

    //01 NSRunloop

    NSRunLoop * runloop1 = [NSRunLoop mainRunLoop];

    //02 CFRunLoopRef

    CFRunLoopRef runloop2 =   CFRunLoopGetMain();

    3.注意点:开一个子线程创建runloop,不是通过alloc init方法创建,而是直接通过调用currentRunLoop方法来创建,它本身是一个懒加载的。

    4.在子线程中,如果不主动获取Runloop的话,那么子线程内部是不会创建Runloop的。可以下载CFRunloopRef的源码,搜索_CFRunloopGet0,查看代码。

    5.Runloop对象是利用字典来进行存储,而且key是对应的线程Value为该线程对应的Runloop。

    2.Runloop应用

    1)NSTimer

    2)ImageView显示:控制方法在特定的模式下可用

    3)PerformSelector

    4)常驻线程:在子线程中开启一个runloop

    5)自动释放池

    第一次创建:进入runloop的时候

    最后一次释放:runloop退出的时候

    其它创建和释放:当runloop即将休眠的时候会把之前的自动释放池释放,然后重新创建一个新的释放池

    相关文章

      网友评论

          本文标题:RunLoop

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