文章目录
- [iOS - Runloop介绍](#iOS - Runloop介绍)
 - 
- [1. 简介](#1. 简介)
 - 
- [1.1 顾名思义](#1.1 顾名思义)
 - [1.2. 应用范畴](#1.2. 应用范畴)
 - [1.3. 如果没有runloop](#1.3. 如果没有runloop)
 - [1.4. 如果有了runloop](#1.4. 如果有了runloop)
 
 - [2. Runloop对象](#2. Runloop对象)
 - [3. Runloop与线程](#3. Runloop与线程)
 - [4. 获取Runloop对象](#4. 获取Runloop对象)
 - 
- [4.1 Foundation](#4.1 Foundation)
 - [4.2 Core Foundation](#4.2 Core Foundation)
 - [4.3 示例](#4.3 示例)
 
 - [5. Runloop相关的类](#5. Runloop相关的类)
 - 
- [5.1 Core Foundation中关于RunLoop的5个类](#5.1 Core Foundation中关于RunLoop的5个类)
 - [5.2 CFRunLoopRef](#5.2 CFRunLoopRef)
 - [5.3 CFRunLoopModeRef](#5.3 CFRunLoopModeRef)
 - [5.4 相关的类之间的关系](#5.4 相关的类之间的关系)
 - 
- [5.4.1 CFRunLoopModeRef](#5.4.1 CFRunLoopModeRef)
 
 - [5.5 Runloop状态](#5.5 Runloop状态)
 - 
- [5.5.1 监听Runloop状态](#5.5.1 监听Runloop状态)
 
 
 
 
iOS - Runloop介绍
1. 简介
1.1 顾名思义
- 运行循环
 - 在程序运行过程中循环做一些事情
 

1.2. 应用范畴
- 定时器(Timer)、PerformSelector
 - GCD Async Main Queue
 - 事件响应、手势识别、界面刷新
 - 网络请求
 - AutoreleasePool
 
1.3. 如果没有runloop

执行完第13行代码后,会即将退出程序
1.4. 如果有了runloop


- 程序并不会马上退出,而是保持运行状态
 - RunLoop的基本作用
- 保持程序的持续运行
 - 处理App中的各种事件(比如触摸事件、定时器事件等)
 - 节省CPU资源,提高程序性能:该做事时做事,该休息时休息
... 
 
2. Runloop对象
- 
iOS中有2套API来访问和使用RunLoop
- 
Foundation:
NSRunLoop - 
Core Foundation:
CFRunLoopRef 
 - 
 - 
NSRunLoop和CFRunLoopRef都代表着RunLoop对象- NSRunLoop是基于CFRunLoopRef的一层
OC包装 - CFRunLoopRef是
开源的 
 - NSRunLoop是基于CFRunLoopRef的一层
 
https://opensource.apple.com/tarballs/CF/

3. Runloop与线程
- 
每条线程都有
唯一的一个与之对应的RunLoop对象 - 
RunLoop保存在一个
全局的Dictionary里,线程作为key,RunLoop作为value - 
线程
刚创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建 - 
RunLoop会在
线程结束时销毁 - 
主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop 
4. 获取Runloop对象
4.1 Foundation
- 
NSRunLoop currentRunLoop\]; `// 获得当前线程的RunLoop对象`
 
4.2 Core Foundation
CFRunLoopGetCurrent();// 获得当前线程的RunLoop对象`- CFRunLoopGetMain(); 
// 获得主线程的RunLoop对象 
4.3 示例

5. Runloop相关的类
5.1 Core Foundation中关于RunLoop的5个类
- CFRunLoopRef
 - CFRunLoopModeRef
 - CFRunLoopSourceRef
 - CFRunLoopTimerRef
 - CFRunLoopObserverRef
 
5.2 CFRunLoopRef

_modes里面装了多个CFRunLoopModeRef对象,其中只有一个mode作为_currentMode
5.3 CFRunLoopModeRef

5.4 相关的类之间的关系
CFRunLoopRef里面装了多个CFRunLoopModeRef对象CFRunLoopModeRef对象里面装的是CFRunLoopSourceRef、CFRunLoopTimerRef、CFRunLoopObserverRef

5.4.1 CFRunLoopModeRef
- 
CFRunLoopModeRef代表RunLoop的
运行模式 - 
一个RunLoop包含
若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer - 
RunLoop启动时
只能选择其中一个Mode,作为currentMode - 
如果需要
切换Mode,只能退出当前Loop,再重新选择一个Mode进入- 不同组的
Source0/Source1/Timer/Observer能分隔开来,互不影响 
 - 不同组的
 - 
如果Mode里
没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出 
5.4.1.1常见的2种Mode
- 
kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行 - 
UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响 
5.5 Runloop状态

5.5.1 监听Runloop状态
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    switch (activity) {
        case kCFRunLoopEntry: {
            NSLog(@"kCFRunLoopEntry");
        }
            break;
        case kCFRunLoopBeforeTimers: {
            NSLog(@"kCFRunLoopBeforeTimers");
        }
            break;
        case kCFRunLoopBeforeSources: {
            NSLog(@"kCFRunLoopBeforeSources");
        }
            break;
        case kCFRunLoopBeforeWaiting: {
            NSLog(@"kCFRunLoopBeforeWaiting");
        }
            break;
        case kCFRunLoopAfterWaiting: {
            NSLog(@"kCFRunLoopAfterWaiting");
        }
            break;
        case kCFRunLoopExit: {
            NSLog(@"kCFRunLoopExit");
        }
            break;;
            
        default:
            break;
    }
});
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopCommonModes);
CFRelease(observer);
        触发一次点击事件:

@oubijiexi