iOS 底层 - runloop的基本认识

本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举原文出处还望见谅与指出,另文章内容如有不妥之处还望指教,万分感谢 !


iOS系统中有两个关于Runloop的对象:NSRunLoopCFRunLoopRef
NSRunloop是Foundation框架提供的,是对CoreFoundation框架提供的CFRunloopRef的封装。
CoreFoundation提供的是纯C语言的API,都是线程安全的,Foundation不是线程安全的。
IOS 中Foundation是不开源的;
iOS 中RunLoop是开源的,在CoreFoundation的开源代码中,可以在这里下载:RunLoop源码

什么是RunLoop

RunLoop顾名思义就是运行循环,是在程序运行中循环做一些事情;有五种状态七种模式

RunLoop的基本作用是什么?有什么意义?系统中在那些地方有用到它 ?实际开发中会有哪些应用 ?

一般多用于以下几种场景:

  • 基本作用:

    • 保持程序的持续运行
    • 处理App中的各种事件:定时器(Timer)、PerformSelector(触摸事件)
    • 节约CPU资源,提高程序性能:该做事时做事,该休息时休息
  • 意义:

    • RunLoop存在的意义是可以保证程序一直处于运行状态,同时还可以处理各种事件;没有RunLoop,代码只要执行完就会马上退出,也就不能够保证程序的持续使用。
  • 应用范畴:

    • GCD;
      GCD的执行逻辑一般是不依赖RunLoop,只有少数需要;
      比如:异步回到主线程刷新UI、dispatch_after()、这样的操作才会交给RunLoop处理
    • 事件响应、手势识别、界面刷新
    • 网络请求
    • AutoreleasePool (自动释放池)
  • 实际开发中应用:

    • 控制线程的生命周期(线程保活)
    • 解决NSTime在滑动时停止工作的问题
    • 监控应用卡顿
    • 性能优化

RunLoop对象简单使用

//获得当前线程的RunLoop对象
[NSRunLoop currentRunLoop]
CFRunLoopGetCurrent()

//获得主线程的RunLoop对象
[NSRunLoop mainRunLoop]    
CFRunLoopGetMain()

RunLoop与线程的关系

  • 每条线程都有唯一的一个与之对应的RunLoop对象
  • RunLoop对象保存在一个全局的Dictionary(字典)里面,线程作为key,RunLoop对象作为value;
  • 线程刚创建出来时并没有RunLoop对象,RunLoop会在第一次获取(currentRunLoop)它时创建
  • RunLoop对象会在线程结束时一同销毁
  • 主线程的RunLoop对象由系统自动获取(创建)

    注意:子线程默认不会开启RunLoop需要注意

GCD函数能单独实现线程保活吗 ?

不能够的,GCD是开辟多线程执行任务,同时能够保证线程安全;就算GCD有相关API可以控制线程生命周期,本质上还是因为GCD内部用到了Runloop。线程的生命周期控制只有通过RunLoop技术才能实现。

你可能感兴趣的:(iOS 底层 - runloop的基本认识)