本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举原文出处还望见谅与指出,另文章内容如有不妥之处还望指教,万分感谢 !
iOS
系统中有两个关于Runloop
的对象:NSRunLoop
和 CFRunLoopRef
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 (自动释放池)
- GCD;
-
实际开发中应用:
- 控制线程的生命周期(线程保活)
- 解决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技术才能实现。
网友评论