iOS之RunLoop

2017-02-22  本文已影响0人  柚子_童鞋

RunLoop 是 iOS 和 OS X 开发中非常基础的一个概念,对于iOS系统上的APP来说:有了RunLoop的存在进而保证程序的持续运行。网上的资料太多,但是太多都比较晦涩,于是自己整理一些;

写在最前:iOS关于RunLoop的学习框架有两套:OC的Foudation框架和C语言的Core Foundation框架;

在看了源码以及相关资料整理一下笔记:
Q:线程与RunLoop之间的关系:
A:一般来讲,每条线程都有唯一的与之对应的RunLoop对象;

Q:RunLoop在何时被创建?
A:在程序启动时候会默认创建主线程,与主线程对应的RunLoop在程序启动时候已自动创建并启动;而子线程的RunLoop则需要手动去创建;

Q:RunLoop在何时被销毁?
A:主线程的RunLoop不会被销毁,而子线程的RunLoop在子线程内的任务结束时被销毁;

Q:RunLoop如何创建?
A:此时要注意,一般的OC语言创建对象是alloc init来创建,RunLoop在源码内部为懒加载设计,当获取到当前的RunLoop为nil,则会自动创建,并且只创建一次。

Q:如何获取RunLoop对象?
A:获取主线程的RunLoop对象:[NSRunLoop mainRunLoop];
获取子线程的RunLoop对象:[NSRunLoop currentRunLoop];

Q:与RunLoop相关的有哪些类?
A:五个类(结合下面的图):
CFRunLoopRef
CFRunLoopModeRef — 运行模式
CFRunLoopTimeRef — 定时器
CFRunLoopSourceRef — 事件
CFRunLoopObserverRef — 观察者


下面我们结合这五个类来一一了解:
CFRunLoopModeRef — 运行模式

系统提供了五种模式:
1,kCFRunLoopDefaultMode:系统默认模式,主线程的RunLoop模式;
2,UITrackingRunLoopMode:界面跟踪Mode,用于跟踪scroview触摸滑动;
3,UIInitializationRunLoopMode:在刚启动APP时进入的第一种Mode,APP启动后该模式即废弃不再使用;
4, GSEventReceiveRunLoopMode:接收系统事件的内部Mode;(graphic service内部绘图渲染等)
5,kCFRunLoopCommonMode:占位模式,并不是真正的Mode

每次RunLoop启动都要指定一个Mode,此ModeCurrentModeRunLoop可以在多个模式之间切换;如果要切换Mode,只能退出Loop,再次重新指定一个Mode;区别开不同的Source/Timer/Observer,使其彼此互不干扰;


CFRunLoopTimeRef — 基于时间的触发器;

其实就是NSTimer,大家对于NSTimer应该都比较熟悉,再次就不做过多解释;


CFRunLoopSourceRef -- 事件源(输入源)

在官方文档上,分类如下:

Port-Based Sources
Custom Input Sources
Cocoa perform Selector Sources

但是在实践过程中我们按照函数调用栈来分:

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


CFRunLoopObserverRef — 观察者模式

能够监听RunLoop状态的改变;
可以监听的事件(或者说状态)见官方文档截图:

kCFRunLoopEntry = (1UL << 0), //即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), //即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2), //即将处理source
kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), //从休眠状态中唤醒
kCFRunLoopExit = (1UL << 7), //即将退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU //``所有的状态

以上就是RunLoop的一些概念性的东西,有些枯燥,在接下来我会结合代码和实际场景进行演示,希望能与大家共同学习,共同进步;

上一篇下一篇

猜你喜欢

热点阅读