RunLoop是什么?
RunLoop是管理事件的一种结构,如何让线程在没有处理消息时休眠以避免资源占用,在有消息到来时立刻被唤醒。
RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行上面 Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 “接受消息->等待->处理” 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。
OSX/iOS 系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。
CFRunLoopRef 是在 CoreFoundation 框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。
NSRunLoop 是基于 CFRunLoopRef 的封装,提供了面向对象的 API,但是这些 API 不是线程安全的。
RunLoop 与线程的关系
首先,iOS 开发中能遇到两个线程对象: pthread_t 和 NSThread。CFRunLoop 是基于 pthread 来管理的。
苹果不允许直接创建 RunLoop,它只提供了两个自动获取的函数:CFRunLoopGetMain() 和 CFRunLoopGetCurrent()。
从上面的代码可以看出,线程和 RunLoop 之间是一一对应的,其关系是保存在一个全局的 Dictionary 里。线程刚创建时并没有 RunLoop,如果你不主动获取,那它一直都不会有。RunLoop 的创建是发生在第一次获取时,RunLoop 的销毁是发生在线程结束时。你只能在一个线程的内部获取其 RunLoop(主线程除外)
运行循环是与线程关联的基础结构的一部分。运行循环是一个事件处理循环,您可以使用它来调度工作并协调接收到的事件。运行循环的目的是保持你的线程忙当有工作要做,把你的线程时没有睡觉。
运行循环管理并不是完全自动的。您还必须设计线程的代码,以便在适当的时候启动运行循环并对传入的事件作出响应。Cocoa和Core Foundation都提供运行循环对象,以帮助您配置和管理线程的运行循环。您的应用程序不需要显式地创建这些对象;每个线程,包括应用程序的主线程,都有一个相关的运行循环对象。不过,只有次要线程需要显式地运行它们的运行循环。应用程序框架在主线程上自动设置和运行运行循环,作为应用程序启动过程的一部分。
网友评论