performselector实现原理(详解performselector应用场景)

RunLoop 学习起来是很抽象,也不好理解,所以一定多看几次,多学学才能学好!这也是中高级 iOS 必须掌握的知识点,面试中经常遇到

什么是 RunLoop?

Run 表示运行,Loop 表示循环。结合在一起就是运行循环的意思。RunLoop 就是在程序运行过程中循环做一些事情.

RunLoop 的应用范畴有哪些?

定时器 (Timer)、PerformSelector

GCD Async Main Queue

事件响应、手势识别、界面刷新

网络请求

AutoreieasePool

上面这些底层都是 RunLoop 在支撑,说白了,如果没有 RunLoop 支撑,上面的这些都无法实现。

如果没有 RunLoop 会发生什么呢?像我们的命令行项目,创建出来默认就是没有 RunLoop,请看下图

performselector实现原理(详解performselector应用场景)

retVal 这个等于 0,当没有事件处理的时候,RunLoop 就会 sleep 就是类似睡觉,一旦有事件需要处理,比如点击、刷新事件等 process_message 就会去处理这个事件,处理完了继续休息,retVal=0,程序就会一直执行,不会退出,这就是 RunLoop 作用。

RunLoop 的基本作用

1.保持程序的持续运行

2.处理 App 中的各种事件(比如触摸事件、定时器事件等)

3.节省了 CPU 资源,提高程序性能:该做事时做事,该休息时休息

获取 RunLoop 对象

iOS 中有 2 套 API 来访问和使用 RunLoop :

Foundation : NSRunLoop (OC 语言里面的)

Core Foundation : CFRunLoopRef (C 语言里面的)

NSRunLoop 和 CFRunLoopRef 都代表着 RunLoop 对象

NSRunLoop 是基于 CFRunLoopRef 的一层 OC 包装

CFRunLoopRef 是开源的.(CFRunLoopRef 参考链接)

其实我们很多都是由 OC 包装出来的,请看下面:

performselector实现原理(详解performselector应用场景)

获取 RunLoop

这里注意 “地址不一样” 因为 NSRunLoop 是对 CFRunLoopDef 做了一层包装,你可以用 OC 的 NSLog(“%@”,[NSRunLoop MainRunLoop]) 获取对比一下,它的地址就是 C 语言获取的地址。主线程只有一个 RunLoop。

RunLoop 与线程

每条线程都有唯一的一个与之对应的 RunLoop 对象(一一对应)

RunLoop 保存在一个全局的 Dictionary 里,线程作为 key,RunLoop 作为 value

线程刚创建的时候并没有 RunLoop 对象,RunLoop 会在第一次获取它时创建

RunLoop 会在线程结束时销毁

主线程的 RunLoop 已经自动创建,子线程默认没有开启 RunLoop。

performselector实现原理(详解performselector应用场景)

从字典也能看出来是一对一的关系。而且确实是第一次获取的时候是空的,然后再去创建这个 RunLoop。

那我们就继续来了解 RunLoop 内部的数据结构,到底是怎么工作的。

RunLoop 相关的类

Core Foundation 中关于 RunLoop 的 5 个类

1.CFRunLoopRef

2.CFRunLoopModeRef

3.CFRunLoopSourceRef

4.CFRunLoopTimerRef

5.CFRunLoopObserverRef

再看下 CFRunLoopRef 的底层源码:

performselector实现原理(详解performselector应用场景)

所以我们来个总结的图:

performselector实现原理(详解performselector应用场景)

Source1

基于 Port 的线程间的通信,系统事件的捕捉。

(两个线程之间相互传递消息的处理,系统事件捕捉,其实也包括触摸事件,只是把事件捕捉到以后传递给 Source0)。

Timer

NSTimer 定时器,performSelector:withObject:afterDelay (这个方法的底层实现也就是 NSTimer 来实现的)。

Observers

用于监听 RunLoop 的状态,UI 的刷新 (BeforeWaiting),Autorelease pool(BeforeWaiting)。

(在 RunLoop 休眠之前都会去执行 UI 的刷新啊、Autorelease pool 的释放等)

以上这些东西,完全就是我们平时开发中经常写的代码,比如设置背景色,设置 frame 等等。

由于 RunLoop 知识点比较多,如果写太多不利于大家的阅读和消化,所以其他内容放在后面介绍!

(0)
小多多的头像小多多创始人

相关推荐

发表回复

登录后才能评论