iOS RunLoop 的总结

145 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

Runloop

Runloop是事件接收和分发机制的一个实现。是线程相关的基础框架的一部分。一个Runloop就是一个事件处理的循环,用来不停的调度工作及处理输入事件。使用runloop的目的就是让你的线程

RunLoop的主要目的:

保证程序执行的线程不会被系统终止,如果没有RunLoop,UIApplicationMain函数执行完毕之后将直接返回,就是说程序一启动然后就结束,在有工作的时候忙于工作,而没有工作的时候处于休眠状态.

什么时候使用Runloop ?

当需要和该线程进行交互的时候才会使用Runloop.

Runloop Mode

一个Runloop可能有几个mode

Runloop Mode 实际上是 SourceTimerObserver 的集合,不同的 Mode 把不同组的Source,Timer和Observer隔绝开来。Runloop 在某个时刻只能跑在一个 Mode 下,处理这一个 Mode 当中的 Source,Timer 和 Observer

苹果文档中提到的 Mode 有五个,分别是:

NSDefaultRunLoopMode:默认的mode,正常情况下都是在这个mode
NSConnectionReplyMode
NSModalPanelRunLoopMode
NSEventTrackingRunLoopMode:使用这个Mode去跟踪来自用户交互的事件(比如UITableView上下滑动)
NSRunLoopCommonModes

iOS 中公开暴露出来的只有 NSDefaultRunLoopModeNSRunLoopCommonModesNSRunLoopCommonModes 实际上是一个 Mode 的集合,默认包括 NSDefaultRunLoopModeNSEventTrackingRunLoopMode

Source

即可以唤醒Runloop的一些事件。比如用户点击了屏幕,就会创建一个input source。

  • source0 : 非系统事件
  • source1 : 系统时间

Timer
我们经常用的NSTimer就属于这一类。

Observer
某个observer可以监听runloop的状态变化,并作出一定反应。

实战

哈哈,讲了这么多云里雾里的原理知识,下边终于到了实战应用环节。

光弄懂是没啥用的,能够实战应用才是硬道理。下面讲解一下RunLoop的几种应用。

NSTimer的使用

NSTimer的使用方法在讲解CFRunLoopTimerRef类的时候详细讲解过,具体参考上边 2.3 CFRunLoopTimerRef

ImageView推迟显示

有时候,我们会遇到这种情况:
当界面中含有UITableView,而且每个UITableViewCell里边都有图片。这时候当我们滚动UITableView的时候,如果有一堆的图片需要显示,那么可能会出现卡顿的现象。

怎么解决这个问题呢?

这时候,我们应该推迟图片的显示,也就是ImageView推迟显示图片。有两种方法:

1. 监听UIScrollView的滚动

因为UITableView继承自UIScrollView,所以我们可以通过监听UIScrollView的滚动,实现UIScrollView相关delegate即可。

2. 利用PerformSelector设置当前线程的RunLoop的运行模式

利用performSelector方法为UIImageView调用setImage:方法,并利用inModes将其设置为RunLoop下NSDefaultRunLoopMode运行模式。代码如下:

[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"tupian"] afterDelay:4.0 inModes:NSDefaultRunLoopMode];

参考

iOS底层学习——RunLoop实现原理 - 掘金 (juejin.cn)