Runloop:运行循环-死循环
主要目的:提高性能,有事情就干,没事情休眠。
参考https://blog.csdn.net/callauxiliary/article/details/107419854
主要应用
1,保证线程一直运行,处理事件,比如触摸事件,时钟事件,都是由runloop完成。
2,优化卡顿:将一次runloop执行完的任务,放到多次runloop中执行。
3,UI滑动时计时不准确的问题,设置定时器的Mode为:NSRunLoopCommonModes。
4,需要在线程上使用performSelector*****方法(运行时方法)。例如
让UITableView、UICollectionView等延迟加载图片
[imageView performSelector:@selector(setImage:) withObject:image afterDelay:0 inModes:@[NSDefaultRunLoopMode]];
这算一个优化点,这里用的defaultMode,就是滚动的时候不加载图片,停止滚动加载图片
Runloop运行原理
当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。每次线程运行RunLoop都会自动处理之前未处理的消息,并且将消息发送给观察者,让事件得到执行。
Runloop的生命周期:在第一次获取时创建,在线程结束时销毁。
Runloop要想跑起来,它的内部必须要有一个mode,这个mode里面必须有source\observer\timer,至少要有其中的一个。
系统默认注册了5个mode
a.kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
b.UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
c.UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
d.GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
e.kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
RunLoop运行时首先根据modeName找到对应mode,如果mode里没有source/timer/observer,直接返回。
主要分为三大步骤:
1、首先根据modeName找到对应的Mode
2、如果model里没有Source/Timer/Observer