一、NSRunLoop的理解
 
     在初学C语言编程的时候,经常会写一种控制台中的程序,程序启动黑色的输入框,等待用户的输入,输入一组数据之后程序继续往下执行程序在等待用户输入数据时会阻塞,这是一种最简单的单线程程序执行的模式。这种简单的编程模型在实际的应用中很难满足用户的需要,比如ios中的app的主线程需要同时响应多种消息,用户触摸事件、timer定时器到时、其它线程发送过来的消息,很自然可以想到为了都能处理到这些消息,那么就在一个while循环中,循环遍历处理这些不同是事件(source),这就是runloop的雏形,也是runloop的含义。
    
     runloop的作用是不是只是简单的循环遍历处理事件呢,当然没那么简单了。首先不同的事件的优先级别是不一样的,用户触摸事件一般高于其它事件类型的,这也是ios系统体验比安卓流畅的一个原因,在一个时间段内主线程收到不同的消息时,runloop优先处理用户交互产生的事件。当然,要达到这种效果,就需要将source分成不同的类型,并把这些类型对应不同的模式(NSRunLoopMode),在某种模式下面只处理指定的几种事件,比如一个UItableView在滑动的时候,主线程的RunLoop会在NSRunloopTrackingMode模式下面运行,这个模式下面是不会处理timer消息的,这样保证在滑动的时候,runloop能一直处理滑动的消息,不停的滑动不停的刷新界面,保证界面的流畅度。
 
     可以想像出来,runloop就类似于一个消息泵,每种事件(source)到达的时候,会在对应的类型的事件队列下面排队,runloop运行在不同模式时从不同的队列中取出消息进行执行,就如下图:
     右边是不同的事件,左边是一个线程中的runloop。那么runloop在一个循环时,就会对应不同的状态,runloop开始,runloop结束,此外还可以想到runloop正在等待消息。对应到真正的类型如下:
    
 
     依次代表的含义是,进入runloop,将要处理timer消息,将要处理其它类型的消息,将要进入等待,结束等待,退出几种含义。
     
二、RunLoop的实现
     
     Runloop的源代码没有真正的源代码,只有找到替代实现cocotron,里面有Runloop的实现,看了之后对Runloop会有更多理解。Runloop是否真的是while循环实现的呢,猜测应该不是,隔一段时间遍历检测这样的效率太低了,类似于poll,需要遍历所有的事件,没有事件响应进入休眠,有事件遍历检测,这样不停休眠唤醒。其实还有更高效率的实现,类似于epoll,在内核中注册事件的回调,需要内核支持。runloop是不是这样实现的不得而知。
 
     官方文档说Runloop是每个线程独有的,可以猜测出Runloop是每个线程结构中的一个对象,只是没有进入running的状态,主线程会默认跑起来。NSTimer需要加入到RunLoop中才会生效,因为是runloop中响应timer消息,想想如果一个Runloop没有跑起来加入一个timer是不会有什么反应的。
 
三、RunLoop的利用
     
     有很多场景下面,我们需要对app的性能进行优化,比如一个滑动列表,我们需要优化FPS,那么我们需要保证在滚动的过程中,主线程不要做多余的事情,比如读取大的图片文件,比如渲染大涨图片,这些都会产生卡顿,有一种场景是,用户下载一张图片,通过通知(同步的方式)的方式告知cell下载成功进行刷新,如果table在滚动的过程中收到这个通知,那么就会对图片进行渲染,图片尺寸小点没关系,大点的图片将会产生卡顿。有没有办法在滑动停止,或者runloop空闲的时候执行某些消息呢?
     下面是我的一种实现,可以下载源代码进行阅读,通过performSelector的方式,将要执行的selector转化成invocation放入队列中,同时检测runloop的状态,空闲的时候再进行执行。
     实际上系统已经考虑到这个场景了,有一种runloopmode是NSConnectionReplyMode,指的是在收到网络回包通知时在这种mode下面响应,而现在大量使用第三方类库的时候没有考虑这个机制。
 
四、RunLoop带来的坏处
     
     我们知道performSelector是在Runloop中响应的,在一轮循环中执行某个selector,这个时候如果在selector中发生了crash,那么会经常看到调用堆栈的上层只是Runloop相关的内容,很难判断出一个是哪里调用的selector。不知道是否有人对此研究,是否可以对调用层进行跟踪。
 
     

NSRunLoop的利用的更多相关文章

  1. NSRunLoop的进一步理解

    iPhone应用开发中关于NSRunLoop的概述是本文要介绍的内容,NSRunLoop是一种更加高明的消息处理模式,他就高明在对消息处理过程进行了更好的抽象和封装,这样才能是的你不用处理一些很琐碎很 ...

  2. NSRunLoop详解

    1.NSRunLoop是IOS消息机制的处理模式 NSRunLoop的主要作用:控制NSRunLoop里面线程的执行和休眠,在有事情做的时候使当前NSRunLoop控制的线程工作,没有事情做让当前NS ...

  3. NSRunLoop 概述和原理

    NSRunLoop 概述和原理 1.什么是NSRunLoop? 我们会经常看到这样的代码: - (IBAction)start:(id)sender { pageStillLoading = YES; ...

  4. 利用RunTime解决由NSTimer导致的内存泄漏

    NSTimer使用场景 用NSTimer来实现每隔一定时间执行制定的任务,例如最常见的广告轮播图,使用NSTimer实现这个功能很简单代码如下 NSTimer *_timer; _timer = [N ...

  5. 第四十三篇、利用NSProxy解决NSTimer内存泄漏问题

    问题描述: 用NSTimer来实现每隔一定时间执行制定的任务,例如最常见的广告轮播图.如果我们在 timerWithTimeInterval:1 target:self 中指定target为当前控制器 ...

  6. 关于NSRunLoop和NSTimer的深入理解

    一.什么是NSRunLoop NSRunLoop是消息机制的处理模式 NSRunLoop的作用在于有事情做的时候使的当前NSRunLoop的线程工作,没有事情做让当前NSRunLoop的线程休眠 NS ...

  7. NSRunLoop原理详解——不再有盲点

    编程最怕的就是有盲点,不确定,而runloop官网对其提及的又很少:那么看完这篇应该使你有底气很多~ RunLoop整体介绍 An event-processing loop, during whic ...

  8. 利用GCD 中的 dispatch_source_timer 给tableViewCell添加动态刷新的计时/倒计时功能

    1.思路一(失败) 在设置好cell 里的内容之后在每个cell 返回时调用定时器事件,更新cell 内容,然后刷新整个表格. - (void)didadida:(UITableViewCell *) ...

  9. 利用NSProxy解决NSTimer内存泄漏问题

    之前写过一篇利用RunTime解决由NSTimer导致的内存泄漏的文章,最近和同事讨论觉得这样写有点复杂,然后发现有NSProxy这么好用的根类,根类,根类,没错NSProxy与NSObject一样是 ...

随机推荐

  1. SpringMVC实现注解式权限验证(转)

    SpringMVC学习系列(9) 之 实现注解式权限验证   对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用serv ...

  2. InnoDB与MyISAM引擎区别

    mysql中InnoDB与MyISAM两种数据库引擎的区别: 一.InnoDB引擎: 1.支持事务性, 2.支持外部键, 3.行级锁, 4.不保存表的具体行数,执行select count(*) fr ...

  3. linux看代码方法和建议

    http://blog.csdn.net/lxl584685501/article/details/46803077

  4. 在2002年的老电脑上安装Debian

    在2002年自己花了家里八千多元买了一台联想昭笔记本电脑.配置是PIII 750 Hz, 128 MB内存(后来升级到了320 MB).那个时候大学里买笔记本电脑的人还不多,宿舍里的同学大都攒的台式机 ...

  5. mybatis学习笔记三(关联关系)

    学习mybatis的关联关系,主要注解在代码上,这里不做解释.配置文件一样的就不贴了 1.关联关系表创建(学生对应老师 多对一) 学生老师表 2.表对应的实体类 package com.home.en ...

  6. Batch File Rename Utility(文件批量改名软件) 1.1.4231

    软件名称: Batch File Rename Utility(文件批量改名软件) 1.1.4231.23098 软件语言: 英文 授权方式: 免费软件 运行环境: Win7 / Vista / Wi ...

  7. C#下在图片文件本地

    //C#下载图片文件到本地,c#,c#下载,下载图片,下载文件,下载函数// 从图片地址下载图片到本地磁盘// 将二进制文件保存到磁盘 using System;using System.Drawin ...

  8. 关于LeetCode的Largest Rectangle in Histogram的低级解法

    在某篇博客见到的Largest Rectangle in Histogram的题目,感觉蛮好玩的,于是想呀想呀,怎么求解呢? 还是先把题目贴上来吧 题目写的很直观,就是找直方图的最大矩形面积,不知道是 ...

  9. hdu 2149 Public Sale 简单博弈

    Problem Description 虽然不想,但是现实总归是现实,Lele始终没有逃过退学的命运,因为他没有拿到奖学金.现在等待他的,就是像FarmJohn一样的农田生涯.要种田得有田才行,Lel ...

  10. ios GCD的使用及封装

    实现代码: CGDHelper /* * Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. * 系统要求:iOS4.0以上. */ #import & ...