iOS - RunLoop总结 by:nixs
发布时间:2023-04-04 11:13:50 所属栏目:教程 来源:
导读:详细示例代码github仓库总结:NIiOS
##### (二十) iOS RunLoop
```
Runloop
RunLoop的应用
- [x] 常驻线程
NSTimer
- [x] 1. 定时器的使用
- [x] 2. 滑动时失
##### (二十) iOS RunLoop
```
Runloop
RunLoop的应用
- [x] 常驻线程
NSTimer
- [x] 1. 定时器的使用
- [x] 2. 滑动时失
|
详细示例代码github仓库总结:NIiOS ##### (二十) iOS RunLoop ``` Runloop RunLoop的应用 - [x] 常驻线程 NSTimer - [x] 1. 定时器的使用 - [x] 2. 滑动时失效 - [x] 3. 不准时 - [x] AutoreleasePool - [x] 事件响应 - [x] 手势识别 - [x] 界面更新 PerformSelecter // 1.和RunLoop不相干,底层直接调用objc_sendMsg方法 - [x] (id)performSelector:(SEL)aSelector withObject:(id)object; // 2. 和RunLoop相关,封装成Source0事件,依赖于RunLoop,若线程无对应的RunLoop,会调用objc_sendMsg执行 - [x] (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait; // 3. 和RunLoop相关,封装成Timers事件 - [x] (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay; 关于 GCD - [x] 在 RunLoop 的源代码中可以看到用到了 GCD 的相关内容,但是 RunLoop 本身和 GCD 并没有直接的关系。 RunLoop中的Mode - [x] 一个RunLoop包含若干个Mode,每个Mode又包含若干个 Source/Timer/Observer。这句话真的是点晴之笔,一句话就把5个相关类的关系说的一清二楚。 - [x] 一个CFRunLoopModeRef对象有一个name,若干source0,source1,timer,observer和port,可以看出事件都是由mode在管理,而RunLoop管理着Mode。 __CFRunLoopMode的五种运行模式(系统默认注册的五个Mode) - [x] 1. kcfRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行 - [x] 2. UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时不受其他 Mode 影响 - [x] 3. UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用,会切换到kcfRunLoopDefaultMode - [x] 4. GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到 - [x] 5. kcfRunLoopCommonModes: 这是一个占位用的Mode,作为标记kcfRunLoopDefaultMode和UITrackingRunLoopMode用,并不是一种真正的Mode CFRunLoopSourceRef - [x] Source0 只包含了一个回调(函数指针),它并不能主动触发事件。使用时,你需要先调用 CFRunLoopSourceSignal (source),将这个 Source 标记为待处理,然后手动调用 CFRunLoopWakeUp (runloop) 来唤醒 RunLoop,让其处理这个事件。 - [x] Source1 包含了一个 mach_port 和一个回调(函数指针),被用于通过内核和其他线程相互发送消息。这种Source 能主动唤醒 RunLoop 的线程,其原理在下面会讲到。 CFRunLoopTimerRef - [x] 是基于时间的触发器 - [x] CFRunLoopTimerRef 是基于时间的触发器,它和 NSTimer 是 toll-free bridged 的,可以混用。其包含一个时间长度和一个回调(函数指针)。当其加入到 RunLoop 时,RunLoop 会注册对应的时间点,当时间点到时,RunLoop 会被唤醒以执行那个回调。 CFRunLoopObserverRef - [x] CFRunLoopObserverRef 是观察者,每个 Observer 都包含了一个回调(函数指针),当 RunLoop 的状态发生变化时,观察者就能通过回调接受到这个变化。 RunLoop的相关类之间关系 RunLoop相关的类有5个 - [x] 1.CFRunLoopRef - [x] 2.CFRunLoopModeRef - [x] 3.CFRunLoopSourceRef - [x] 4.CFRunLoopTimerRef - [x] 5.CFRunLoopObserverRef 那么每个类都是什么呢? - [x] 1.第一个类我在前面已经剖析过了,它就是RunLoop对象所属于的类 - [x] 2.CFRunLoopModeRef 是 RunLoop 当前的一个运行模式,什么是运行模式呢?我会在RunLoop和Mode这一节仔细讲解 - [x] 3.CFRunLoopSourceRef和CFRunLoopTimerRef是RunLoop处理的消息类型 - [x] 4.CFRunLoopObserverRef监听RunLoop运行状态的一个类 各个类之间的关系 - [x] 1.一个RunLoop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer。 - [x] 2.每次调用 RunLoop的主函数时,只能指定其中一个 Mode,这个Mode被称作CurrentMode。 - [x] 3.如果需要切换 Mode,只能退出Loop,再重新指定一个Mode进入。这样做主要是为了分隔开不同组的 Source/Timer/Observer,让其互不影响。 - [x] 4.如果一个 mode中一个Source/Timer/Observer 都没有,则RunLoop会直接退出,不进入循环。 各个类的作用 - [x] 1.CFRunLoopRef是一个CFRunLoop结构体的指针,所以说它的职责就是CFRunLoop的职责,运行循环,处理事件,保持运行 - [x] 2.CFRunLoopModeRef运行模式,模式下对应多个处理源,具体有哪些模式我会在RunLoop和Mode这一节仔细讲解 3.CFRunLoopSourceRef是事件产生的地方。Source有两个版本:Source0 和 Source1。 - [x] 1.source0触摸事件处理 - [x] 2.source1基于Port的线程见通信 - [x] 4.CFRunLoopTimerRefNSTimer的运用 - [x] 5.CFRunLoopObserverRef用于监听RunLoop的状态,UI刷新,自动释放池 RunLoop和线程 - [x] 1.RunLoop是基于线程来管理的,它们一一对应,共同存储在一个全局区的runLoopDict中,线程是key,RunLoop是value。 - [x] 2.RunLoop的创建:主线程所对应RunLoop在程序一启动创建主线程的时候系统就会自动为我们创建好,而子线程所对应的RunLoop并不是在子线程创建出来的时候就创建好的,而是在我们获取该子线程所对应的RunLoop时才创建出来的,换句话说,如果你不获取一个子线程的RunLoop,那么它的RunLoop就永远不会被创建。 - [x] 3.RunLoop的获取:我们可以通过一个指定的线程从runLoopDict中获取它所对应的RunLoop。 - [x] 4.RunLoop的销毁:系统在创建RunLoop的时候,会注册一个回调,确保线程在销毁的同时,也销毁掉其对应的RunLoop。 CFRunLoopRef对象源码剖析 - [x] NSRunLoop对象是基于CFRunLoopRef的,并且CFRunLoopRef是基于c语言的,线程安全 RunLoop对象的获取 CoreFoundation CFRunLoopRef对象 - [x] CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象 - [x] CFRunLoopGetMain(); // 获得主线程的RunLoop对象 Fundation框架 (基于CFRunLoopRef的封装) NSRunLoop对象 - [x] [NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象 - [x] [NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象 RunLoop在何处开启? - [x] 在UIApplicationMain函数中,开启了一个和主线程相关的RunLoop,导致UIApplicationMain不会返回,一直在运行中,也就保证了程序的持续运行 RunLoop的作用 1.保持程序持续运行 - [x] 程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop,RunLoop保证主线程不会被销毁,也就保证了程序的持续运行 2.处理App中的各种事件 - [x] 1.定时器(Timer)、方法调用(PerformSelector) - [x] 2.GCD Async Main Queue - [x] 3.事件响应、手势识别、界面刷新 - [x] 4.网络请求 - [x] 5.自动释放池 AutoreleasePool 3.节省cpu资源,提高程序性能 - [x] 程序运行起来时,当什么操作都没有做的时候,RunLoop就告诉CUP,现在没有事情做,我要去休息,这时CUP就会将其资源释放出来去做其他的事情,当有事情做的时候RunLoop就会立马起来去做事情 什么是RunLoop? - [x] 之所以,iOS App 能持续响应,保证程序运行状态,在于其有一个事件循环——Event Loop - [x] 事件循环机制,即线程能随时响应并处理事件的机制。这种机制要求线程不能退出,而且需要高效的完成事件调度与处理。 - [x] 事件循环在很多编程语言,或者说不同的操作系统层面都支持。比如 JS中的事件循环、Windows下的消息循环,在 iOS/macOS 下,该机制就称为 RunLoop。 举一个生活中的???? - [x] 进程是一家工厂,线程是一个流水线,RunLoop就是流水线上的主管;当工厂接到商家的订单分配给这个流水线时,RunLoop就启动这个流水线,让流水线动起来,生产产品;当产品生产完毕时,RunLoop就会暂时停下流水线,节约资源。 - [x] RunLoop管理流水线,流水线才不会因为无所事事被工厂销毁;而不需要流水线时,就会辞退RunLoop这个主管,即退出线程,把所有资源释放。 ``` (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
