1.什么是NSRunLoop?

我们会经常看到这样的代码:

- (IBAction)start:(id)sender

{

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中截取):

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){

...

while (GetMessage(&msg, NULL, 0, 0)){

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

}

可以看到在GetMessage之后就去分发处理消息了,而iOS中main函数中只是调用了UIApplicationMain,那么我们可以介意猜出UIApplicationMain在初始化完成之后就会进入这样一个情形:

int 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,有图有真相:

现在会过头来看看刚才的那个会“暂停”代码的例子,有没有更加深入的认识了呢?

CocoaChina社区原帖:http://www.cocoachina.com/bbs/read.php?tid=108067

转载于:https://www.cnblogs.com/max5945/archive/2012/07/18/2597103.html

NSRunLoop 概述和原理相关推荐

  1. 集群概述及原理笔记(1)

    it你好linux学习文档之集群概述及原理笔记(1) 一 前言 目前,越来越多的网站采用Linux操作系统,提供邮件.Web.文件存储.数据库等服务.也有非常多的公司在企业内部网中利用Linux服务器 ...

  2. mysql 基于语句的复制_MySQL 复制 - 性能与扩展性的基石 1:概述及其原理

    1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步.接下来,我们将从复制概述及原理.复制的配置.常 ...

  3. MySQL 复制 - 性能与扩展性的基石:概述及其原理

    1. 复制概述 MySQL 内置的复制功能是构建基于 MySQL 的大规模.高性能应用的基础,复制解决的基本问题是让一台服务器的数据与其他服务器保持同步.接下来,我们将从复制概述及原理.复制的配置.常 ...

  4. 大数据平台,Hadoop集群架构,概述及原理

    目录 一,大数据平台架构概述 1,大数据概念 2,大数据的特征 3,大数据的处理流程和相关技术 4,大数据平台架构的特点 5,大数据平台架构原理 二,Hadoop集群概述 1,HDFS 2,MapRe ...

  5. WPS JASPI加载项 JSAPI概述及原理JSAPI集成开发文档

    JSAPI概述及原理 : [金山文档]JSAPI概述及原理 https://kdocs.cn/l/skWT29577eEE JSAPI集成开发文档 [金山文档]JSAPI集成开发文档 https:// ...

  6. Struts2_day04--课程介绍_Struts2拦截器概述底层原理_重要的概念

    Struts2_day04 上节内容 今天内容 Struts2拦截器概述 拦截器底层原理 重要的概念 自定义拦截器 自定义登录拦截器 Struts2的标签库 Struts2表单标签(会用) Strut ...

  7. 3 关于数据仓库维度数据处理的方法探究系列——缓慢变化维概述和原理

    缓慢变化维 Slowly Changing Dimensions( A typical slowly changing dimension is a product dimension in whic ...

  8. NSRunLoop概述(转)

    1.什么是NSRunLoop? 我们会经常看到这样的代码: 1 2 3 4 5 6 7 8 9 10 - (IBAction)start:(id)sender { pageStillLoading = ...

  9. 快速构建Windows 8风格应用14-ShareContract概述及原理

    本篇博文主要介绍Share Contract概述.Share Contract实现原理.实现Share Contract意义. Share Contract概述 我们都知道Windows 8中包含3类 ...

最新文章

  1. leetcode解题文件夹
  2. apache 开启 gzip 压缩服务
  3. 基于 HTML5 的 WebGL 自定义 3D 摄像头监控模型
  4. 画闭合的多边形 - HTML5 Canvas 作图
  5. C++笔记-基于邻接矩阵的BFS(宽度优先遍历)
  6. 【机器学习】机器学习从零到掌握之四 -- 教你使用可视化分析数据
  7. 2011年中期业绩预增前20家公司
  8. Python实现多线程并发下载大文件(断点续传支持)
  9. favicon.ico图标在线制作+ico下载
  10. 黄金自己怎么用计算计算机数,黄金分割点计算器
  11. 如何在GraphPad Prism 里创建条形图?
  12. 基于 Web SDK 实现视频通话场景 | 声网 SDK 教程
  13. 【转】Jackson之多态反序列化(父类转不同子类)
  14. C语言制作个人通讯录管理系统—超详解(附源码)
  15. 五行Python自动换你的电脑桌面壁纸(内附源码和exe)
  16. 基于STM32F103RC硬件IIC驱动18位AD MCP3421驱动开发
  17. 2020年出生人口会大跌吗?解读人口数据
  18. DuiLib学习笔记1.编译运行demo
  19. android java 启用4g_android下4G上网卡
  20. Linux 发展史,以及常用的一些命令行。

热门文章

  1. java String类
  2. neo4j 增 create
  3. Python Windows文件操作
  4. Pandas 求余运算
  5. php windows 网络流量,PHP系统流量分析的程序
  6. 2019年,瑞云渲染做了这些事……
  7. 信贷系统学习总结(2)——现金贷之借贷模式与前端产品
  8. Spring MVC学习总结(7)——Spring MVC整合Ehcache缓存框架
  9. Spring学习总结(12)——Druid连接池及监控在spring配置
  10. celery java_Python的Java Celery项目相当于什么?