看@sunnyxx runloop视频笔记

最近公司项目不是很忙,所以想着自己该学习一波了。翻看了存货发现这个这个视频早就放到网盘了但是一直都没看,所以赶紧看了看,受益匪浅,现在整理一下笔记,以备不时之需。

runloops 的应用

重点说一下Run Loops 在Cocoa中的使用场景:

1.NSTimer:完全根据runloop封装,没有runloop的话NSTimer完全就是一条废汪。默认情况下开启一个定时器就默认放到runloop下去跑,
2.UIEvent:事件从产生到分发都是由runloop执行。
3.Autorelease:自动释放机制也是在runloop中执行
4.NSObject(NSDelayedPerforming)

- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;

5.NSObject(NSThreadPerformaAddition):

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array

常用的几种延时函数之一也是通过runloop机制执行
6.CADisplayLink:每画一帧动画就会有一个回调(我记得在哪看过说CADisplayLink定时器的精度会高于NSTimer,不过我这个渣渣没有用过CADisplayLink)可能就是因为默认情况下NSTimer会有被中断的风险所有精度不好
7.CATransition、CAAnimation转场动画,UI动画都会在runloop里去跑,类似于定时器的功能
8.AFNetworking:(下面有详细介绍)
9.dispatch_get_main_queue():(下面有详细介绍)

调用堆栈

调用顺序 :start(dyId)把程序调用起来 -> main函数调用了UIApplicationMain函数 -> GSEventRunModal(Graphics Services)处理硬件输入(点击等 所有的UI事件都是他发出来的) -> RunLoop层 -> 应用层。

NSThread、Runloop 、Mode对应关系

一个线程里可以有多个runloop,一个Runloop可以有多个RunloopMode但是必须为嵌套结构,主线程默认开启,子线程默认关闭,所以他俩是一对一的关系。RunLoopMode 和下面的三种model是树枝形结构都在mode内部。里面是数组结构往里添加。


RunLoopTimer 封装

我们初级渣渣最常用的mode啦,其他的多为系统内部使用,平时应用开发过程中基本上用不着


核心函数
RunLoopSource

结构体封装

重点是Mach port驱动轻量级进程间通信方式,某个进程往port发消息,其他进程监听这个端口就能收到消息(貌似都是这个套路啊)

RunLoopObserver

类似于代理,例如7种状态CAAnimation动画在beforeWaiting 和AfterWaiting中执行以上三种使用场景就是最基础最核心的三种mode,个人认为普通开发者最常用的就是第一种

RunLoopMode四种使用模式

四种RunLoop启动方式,稍微有点基础知识的人应该都知道啦
NSDefaultRunloopMode:默认状态,空闲状态,开启定时器时如果不特殊指定默认就是使用这种mode执行。
UITrackingRunLoopMode:滑动ScrollView时调用,特别为防止滑动时降低卡顿而设置,默认情况下此状态下定时器就停了,例如滑动微信聊天记录时GIF动画就停止了。
UIInitalizationRunLoopMode:私有,APP启动时使用,这算系统级别的mode不是我们普通人能用的。
NSRunLoopCommonMode:Mode集合比如你有一个特别重要的定时器,即使牺牲滑动效果也必须保留,那你可以选用此种mode 他可以兼顾NSDefaultRunloopModeUITrackingRunLoopMode例如见下图
NSRunLoopCommonModes使用场景

RunLoopObserver 与Autorelease Pool

面试热门问题:Autorelease Pool 什么时候释放?
简单说是在RunLoop执行完前检测到可以释放Autorelease对象了再进行释放,所以释放时机不会是实时的,其中的原理如上图所示。RunLoop会维护一个栈,先将Autorelease对象push进去,当检测到需要pop的时候会在RunLoop轮询完前进行释放了

RunLoopMode切换

UIKit框架偷偷干了这个工作,有新的RunLoop会push进去,停掉之前的mode 再开始新的mode,当新的结束完了再pop出去,然后再执行上一个。在执行新的mode的时候,上一个mode会停止mode只有一个或者嵌套的关系,在这不存在嵌套关系。
GCD与RunLoop的关系

虽然GCD 与 RunLoop 部分功能类似,但是他俩没有啥子关系,GCD的定时器啥的与Runloop一样都是都是系统维护的,唯一有关系的就是dispatch_get_main_queue()与Runloop 获取主线程是一致的,因为程序的主线程只能有一个,不能不同,还有dispatch_get_main_queue()在屌起主线程的时候是在Runloop下执行的。

Runloop的挂起与唤醒

RunLoop伪代码

经过提前的说明,这个伪代码现在很好看懂了,对于粗略了解原理来说简直就是福音,不过细节的话还得看真正源码

AFN中的RunLoop

这个很好理解,为了节省资源避免频繁创建释放线程耗费资源,AFN会有创建一条常驻线程,然后所有的网络都是异步的有这个专用线程执行。

以下几种是不同的应用,我这才疏学浅没太完全消化也不太好直接写,可以先慢慢看,之后分析。。。


屏幕快照 2018-05-22 下午3.47.35.png

屏幕快照 2018-05-22 下午4.08.53.png

屏幕快照 2018-05-22 下午9.17.08.png

屏幕快照 2018-05-22 下午9.18.36.png

你可能感兴趣的:(看@sunnyxx runloop视频笔记)