IOS RunLoop介绍

来源:互联网 发布:今日目标软件功能 编辑:程序博客网 时间:2024/05/17 07:55

RunLoop

那什么是RunLoop呢?
从字面意思上看,就是从字面意思看
- 运行循环
- 跑圈
那它有什么作用?
1.保持程序的持续运行
2.处理App中的各种事件(比如触摸事件、定时器事件、Selector事件)
3.节省CPU资源,提高程序性能:该做事时做事,该休息时休息…
如果没有RunLoop程序会怎么样呢?
如图:这里写图片描述
那如果有了RunLoop呢
如图:这里写图片描述

首先看ios程序的入口main函数
这里写图片描述
**第14行代码的UIApplicationMain函数内部就启动了一个RunLoop
所以UIApplicationMain函数一直没有返回,保持了程序的持续运行
这个默认启动的RunLoop是跟主线程相关联的**
那ios总有哪些Runloop对象呢?
其实iOS中有iOS中有2套API来访问和使用RunLoop
一是Foundation框架中的NSRunLoop
二是Core Foundation框架中的CFRunLoopRef
NSRunLoop和CFRunLoopRef都代表着RunLoop对象,NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)。
关于RunLoop的资料苹果的官网的地址是https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
还有呢RunLoop是开源的,
http://opensource.apple.com/source/CF/CF-1151.16/

好了 Runloop的简单介绍完了,下面来看看RunLoop和线程的关系

每条线程都有唯一的一个与之对应的RunLoop对象

主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建

RunLoop在第一次获取时创建,在线程结束时销毁

那怎么获取RunLoop对象呢
在Foundation框架中:
[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
在Core Foundation框架中:
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象
那RunLoop相关类有哪些呢?
Core Foundation中关于RunLoop的5个类
- CFRunLoopRef
- CFRunLoopModeRef
- CFRunLoopSourceRef
- CFRunLoopTimerRef
- CFRunLoopObserverRef

Alt text
那下面来看看CFRunLoopModeRef类
CFRunLoopModeRef代表RunLoop的运行模式
一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer

每次RunLoop启动时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode

如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入

这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响

系统默认注册了5个Mode:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行

UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用

GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到

kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
看完了CFRunLoopModeRef,那看看CFRunLoopSourceRef
CFRunLoopSourceRef是事件源(输入源)

以前的分法
Port-Based Sources
Custom Input Sources
Cocoa Perform Selector Sources

现在的分法
Source0:非基于Port的
Source1:基于Port的
然后呢看看CFRunLoopTimerRef
CFRunLoopTimerRef是基于时间的触发器

基本上说的就是NSTimer
那CFRunLoopObserverRef又是什么样的呢
CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变

可以监听的时间点有以下几个
Alt text
看看RunLoop处理逻辑-官方版
Alt text
RunLoop处理逻辑-官方版
Alt text
网友整理版本
Alt text
RunLoop应用
NSTimer
ImageView显示
PerformSelector
常驻线程
自动释放池

0 0
原创粉丝点击