NSRunLoop概述和原理
1.什么是NSRunLoop?
我们会经常看到这样的代码:
{
pageStillLoading = YES;
[NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];
[progress setHidden:NO];
while (pageStillLoading) {
[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[progress setHidden:YES];
}
这段代码很神奇的,因为他会“暂停”代码运行,而且程序运行不会因为这里有一个while循环而受到影响。在[progress setHidden:NO]执行之后,整个函数想暂停了一样停在循环里面,等loadPageInBackground里面的操作都完成了以后才让 [progress setHidden:YES]运行。这样做就显得简介,而且逻辑很清晰。如果你不这样做,你就需要在loadPageInBackground里面表示 load完成的地方调用[progress setHidden:YES],显得代码不紧凑而且容易出错。
那么具体什么是NSRunLoop呢?其实NSRunLoop的本质是一个消息机制的处理模式。如果你对vc++编程有一定了解,在windows中,有 一系列很重要的函数SendMessage,PostMessage,GetMessage,这些都是有关消息传递处理的API。但是在你进入到 Cocoa的编程世界里面,我不知道你是不是走的太快太匆忙而忽视了这个很重要的问题,Cocoa里面就没有提及到任何关于消息处理的API,开发者从来 也没有自己去关心过消息的传递过程,好像一切都是那么自然,像大自然一样自然?在Cocoa里面你再也不用去自己定义WM_COMMAD_XXX这样的宏 来标识某个消息,也不用在switch-case里面去对特定的消息做特别的处理。难道是Cocoa里面就没有了消息机制?答案是否定的,只是Apple 在设计消息处理的时候采用了一个更加高明的模式,那就是RunLoop。
2. NSRunLoop工作原理
接下来看一下NSRunLoop具体的工作原理,首先是官方文档提供的说法,看图:
通过所有的“消息”都被添加到了NSRunLoop中去,而在这里这些消息并分为“input source”和“Timer source” 并在循环中检查是不是有事件需要发生,如果需要那么就调用相应的函数处理。为了更清晰的解释,我们来对比VC++和iOS消息处理过程。
VC++中在一切初始化都完成之后程序就开始这样一个循环了(代码是从户sir mfc程序设计课程的slides中截取):
...
while (GetMessage(&msg, NULL, 0, 0)){
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
可以看到在GetMessage之后就去分发处理消息了,而iOS中main函数中只是调用了UIApplicationMain,那么我们可以介意猜出UIApplicationMain在初始化完成之后就会进入这样一个情形:
...
while(running){
[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
...
}
所以在UIApplicationMain中也是同样在不断处理runloop才是的程序没有退出。刚才的我说了NSRunLoop是一种更加高明的消息 处理模式,他就高明在对消息处理过程进行了更好的抽象和封装,这样才能是的你不用处理一些很琐碎很低层次的具体消息的处理,在NSRunLoop中每一个 消息就被打包在input source或者是timer source中了,当需要处理的时候就直接调用其中包含的相应对象的处理函数了。所以对外部的开发人员来讲,你感受到的就是,把source/timer 加入到runloop中,然后在适当的时候类似于[receiver action]这样的事情发生了。甚至很多时候,你都没有感受到整个过程前半部分,你只是感觉到了你的某个对象的某个函数调用了。比如在UIView被触 摸时会用touchesBegan/touchesMoved等等函数被调用,也许你会想,“该死的,我都不知道在那里被告知有触摸消息,这些处理函数就 被调用了!?”所以,消息是有的,只是runloop已经帮你做了!为了证明我的观点,我截取了一张debug touchesBegan的call stack,有图有真相:
现在会过头来看看刚才的那个会“暂停”代码的例子,有没有更加深入的认识了呢?
NSRunLoop概述和原理的更多相关文章
- NSRunLoop 概述和原理
NSRunLoop 概述和原理 1.什么是NSRunLoop? 我们会经常看到这样的代码: - (IBAction)start:(id)sender { pageStillLoading = YES; ...
- 快速构建Windows 8风格应用14-ShareContract概述及原理
原文:快速构建Windows 8风格应用14-ShareContract概述及原理 本篇博文主要介绍Share Contract概述.Share Contract实现原理.实现Share Contra ...
- 快速构建Windows 8风格应用12-SearchContract概述及原理
原文:快速构建Windows 8风格应用12-SearchContract概述及原理 本篇博文主要介绍Search Contract概述.Search Contract面板结构剖析.Search Co ...
- MySQL 复制 - 性能与扩展性的基石 1:概述及其原理
1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步. 接下来,我们将从复制概述及原理.复制的配置. ...
- MySQL 复制 - 性能与扩展性的基石:概述及其原理
原文:MySQL 复制 - 性能与扩展性的基石:概述及其原理 1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他 ...
- HA 高可用集群概述及其原理解析
HA 高可用集群概述及其原理解析 1. 概述 1)所谓HA(High Available),即高可用(7*24小时不中断服务). 2)实现高可用最关键的策略是消除单点故障.HA严格来说应该分成各个组件 ...
- Struts2_day04--课程介绍_Struts2拦截器概述&底层原理_重要的概念
Struts2_day04 上节内容 今天内容 Struts2拦截器概述 拦截器底层原理 重要的概念 自定义拦截器 自定义登录拦截器 Struts2的标签库 Struts2表单标签(会用) Strut ...
- IOS中的多线程和NSRunLoop概述(转载)
线程概述 有些程序是一条直线,从起点到终点,如Hello World,运行打印完,它的生命周期便结束了:有些程序是一个圆,不断循环,直到将它切断,如操作系统,一直运行直到你关机. 一个运行着的程序就 ...
- 18. HTTP协议一:概述、原理、版本、请求方法
HTTP协议概述 HTTP协议就是我们常说的超文本协议(HyperText Transfer Protocol).HTTP协议是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准. ...
随机推荐
- 将序列化成json格式的日期(毫秒数)转成日期格式
<script> $(function () { loadInfo(); }) function loadInfo() { $.post("InfoList.ashx" ...
- 关于ScrollView和listview的冲突关于的滑动和宽度
listview和ScrollView嵌套有两个冲突,关于listview显示不全的问题和listview和scrollview的滑动冲突 自定义listview package com.exmple ...
- QTP
QTP支持功能测试和回归测试的自动化. 支持录制功能,可以对脚本设置检查点,也可以进行参数化.可以在一个ACTION中调用另外一个ACTION action可以调用外部脚本.可以复制已有的ACTION ...
- 转 C# 装箱和拆箱[整理]
1. 装箱和拆箱是一个抽象的概念 2. 装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的 ...
- java中的23中设计模式(转载的,有时间一定要熟读)
设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- 在用busybox制作系统过程中遇到的问题
遇到的问题: 1.开机报错: 在做完整个系统之后重启出现了这个报错 VFS: Cannot open root device "sda2" or unknown-block(0,0 ...
- Spring RabbitMq
spring-rabbitmq.xml文件内容如下: <?xml version="1.0" encoding="UTF-8"?><beans ...
- 各种浏览器(IE,Firefox,Chrome,Opera)COOKIE修改方法[转]
各种浏览器(IE,Firefox,Chrome,Opera)COOKIE修改方法[转] 网站通过 Cookie 保存了我们访问网站的信息,在不同的浏览器中修改 Cookie 可以如下操作: Firef ...
- 教你解决Sublime Text中文乱码问题
教你解决Sublime Text中文乱码问题[转载自成长的企鹅] Sublime Text 2是一个非常不错的源代码及文本编辑器,但是不支持GB2312和GBK编码在很多情况下会非常麻烦. ...
- jquery总结05-常用事件03-键盘事件
键盘事件 .keydown() 键盘按下触发,返回的的是键盘按键代码 .keyup() 键盘松手触发,返回的是键盘按键代码 .keypress() 键盘按下触发,返回的是敲击的字符的ASCII码