- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
北京iOS培训课浅谈RunLoop
北京iOS培训课程浅谈RunLoop
我会从几个方面阐述RunLoop:
1.RunLoop的概念
2.RunLoop 与线程的关系
3.苹果用RunLoop实现的功能
请大家跟随我一起开始了解RunLoop。
1.RunLoop 的概念
一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。如果我们需要一个机制,让线程能随时处理事件但并不退出,通常的代码逻辑是这样的:
Crayon Syntax Highlighter v2.7.1
function loop() {
initialize();
do {
var message = get_next_message();
process_message(message);
} while (message != quit);
}
1
2
3
4
5
6
7 functionloop(){
????initialize();
????do{
????????varmessage = get_next_message();
????????process_message(message);
????}while(message != quit);
} 这种模型通常被称作Event Loop。 Event Loop 在很多系统和框架里都有实现,比如 Node.js 的事件处理,比如 Windows 程序的消息循环,再比如 OSX/iOS里的RunLoop。实现这种模型的关键点在于:如何管理事件/消息,如何让线程在没有处理消息时休眠以避免资源占用、在有消息到来时立刻被唤醒。
所以,RunLoop实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行上面 Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 接受消息-等待-处理 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。
OSX/iOS系统中,提供了两个这样的对象:NSRunLoop和CFRunLoopRef。
CFRunLoopRef是在CoreFoundation框架内的,它提供了纯 C 函数的 API,所有这些 API 都是线程安全的。
NSRunLoop是基于CFRunLoopRef的封装,提供了面向对象的 API,但是这些 API 不是线程安全的。
2.RunLoop 与线程的关系
首先,iOS开发中能遇到两个线程对象: pthread_t和NSThread。过去苹果有份文档标明了NSThread只是pthread_t的封装,但那份文档已经失效了,现在它们也有可能都是直接包装自最底层的mach thread。苹果并没有提供这两个对象相互转换的接口,但不管怎么样,可以肯定的是pthread_t和NSThread是一一对应的。比如,你可以通过pthread_main_thread_np() 或 [NSThreadmainThread] 来获取主线程;也可以通过pthread_self() 或 [NSThreadcurrentThread] 来获取当前线程。CFRunLoop是基于pthread来管理的。
苹果不允许直接创建RunLoop,它只提供了两个自动获取的函数:CFRunLoopGetMain() 和CFRunLoopGetCurrent()。线程和RunLoop之间是一一对应的,其关系是保存在一个全局的 Dictionary 里。线程刚创建时并没有RunLoop,如果你不主动获取,那它一直都不会有。RunLoop的创建是发生在第一次获取时,RunLoop的销毁是发生在线程结束时。你只能在一个线程的内部获取其RunLoop(主线程除外)。
3.苹果用RunLoop实现的功能
AutoreleasePool
App启动后,苹果在主线程RunLoop里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()。
第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池。其 order 是-2147483647,优先级最高,保证创建释放池发生在其他所有回调之前。
第二个 Observer 监视了两个事件:BeforeWaiting(准备进入休眠) 时调用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优
文档评论(0)