Runloop

6 篇文章 0 订阅
1 篇文章 0 订阅

一、什么是 Runloop ?
1、从字面上讲就是运行循环;
2、它内部就是 do-while 循环,在这个循环内部不断地处理各种任务;
3、一个线程对应一个 RunLoop,主线程的 RunLoop 默认已经启动,子线程的 RunLoop 得手动启动(调用 run 方法);
4、 RunLoop 只能选择一个 Mode启动,如果当前 Mode 中没有任何 Source(Sources0、Sources1)、Timer,那么就直接退出 RunLoop;
5、 基本的作用就是保持程序的持续运行,处理 app 中的各种事件。通过 runloop ,有事运行,没事就休息,可以节省 cpu 资源,提高程序性能。

二、RunLoop 对象
iOS 中有 2 套 API 来访问和使用 RunLoop
1>. Foundation: NSRunLoop
2>. Core Foundation: CFRunLoop
3>. NSRunLoop 和 CFRunLoopRef 都代表着 RunLoop 对象
4>. NSRunLoop 是基于 CFRunLoopRef 的一层OC包装,所以要了解 RunLoop 内部结构,需要多研究 CFRunLoopRef 层面的 API。

三、RunLoop 与线程
1>. 每条线程都有唯一的一个与之对应的 RunLoop 对象。
2>. 主线程的 RunLoop 已经自动创建好了,子线程的 RunLoop 需要主动创建。
3>. RunLoop 在第一次获取时创建,在线程结束时销毁。

四、获得 RunLoop 对象
1>. Foundation

[NSRunLoop currentRunLoop]; // 获取当前线程的 RunLoop 对象
[NSRunLoop mainRunLoop]; // 获得主线程的 RunLoop 对象

2>. Core Foundation

CFRunLoopGetCurrent(); // 获得当前线程的 RunLoop 对象
CFRunLoopGetMain(); // 获得主线程的 RunLoop 对象

五、RunLoop 相关类
Core Foundation 中关于 RunLoop 的5个类

CFRunLoopRef
CFRunLoopModeRef
CFRunLoopSourceRef
CFRunLoopTimerRef
CFRunLoopObserverRef

1>. CFRunLoopModeRef
**、CFRunLoopModeRef 代表 RunLoop 的运行模式。
**、一个 RunLoop 包含若干个 Mode ,每个Mode 又包含若干个(set)Source/(array)Timer/(array)Observer
**、每次 RunLoop 启动时,只能指定其中一个 Mode ,这个 Mode 被称作 CurrentMode
**、如果需要切换 Mode ,只能退出 Loop ,再重新指定一个 Mode 进入
**、这样做主要是为了分隔开不同组的 Source/Timer/Observer, 让其互不影响
**、mode 主要是用来指定事件在运行循环中的优先级的,分为:

NSDefaultRunLoopMode (kCFRunLoopDefaultMode):默认,空闲状态。
UITrackingRunLoopMode :ScrollView 滑动时会切换到该 Mode
UIInitializationRunLoopMode :run loop 启动时,会切换到该 Mode
NSRunLoopCommonModes (kCFRunLoopCommonModes) :Mode 集合,苹果公开提供的Mode 有两个:
    NSDefaultRunLoopMode (kCFRunLoopDefaultMode)
    NSRunLoopCommonModes (kCFRunLoopCommonModes)

2>. CFRunLoopTimerRef
CFRunLoopSourceRef 是事件源(输入源)
按照官方文档,Source 的分类
Port-Based Sources
Custom Input Sources
Cocoa Perform Selector Sources
按照函数调用栈, Source 的分类
Source0 :非基于 Port 的
Source1 :基于 Port 的,通过内核和其他线程通信,接收、分发系统事件。

3>. CFRunLoopObserverRef
**、CFRunLoopObserverRef 是观察者,能够监听RunLoop 的状态改变
**、可以监听的时间点有以下几个:

kcfRunLoopEntry (即将进入 loop// 1
kcfRunLoopBeforeTimers (即将处理 timer)// 2
kcfRunLoopBeforeSources (即将处理 source)// 4
kcfRunLoopBeforeWaiting (即将进入休眠)// 32
kcfRunLoopAfterWaiting (刚从休眠中唤醒)// 64
kcfRunLoopExit (即将退出 loop// 128

**、添加 Observer

CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(),kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    NSLog(@"---监听到 RunLoop 状态发生改变 --- %zd", activity);
});

// 添加观察者:监听 RunLoop 的状态
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);

// 释放 Observer
CFRelease(observer);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值