一、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. CODE[VS]-机票打折-浮点数处理-天梯青铜

    题目描述 Description 输入机票原价(3到4位的正整数,单位:元),再输入机票打折率(小数点后最多一位数字).编程计算打折后机票 的实际价格(单位:元.计算结果要将个位数四舍五入到十位数“元 ...

  2. Webupload + MVC 之上传下载

    最近工作中用到了 MVC 的上传及下载 , 写下感受 本项目中用到的是百度的webuploader <!--引入Jquery--> <script src="~/Conte ...

  3. 2.开启TFTP,NFS,SAMBA,SSH服务

    一.TFTP (1)dpkg -s tftp-hpa查看服务器端是否安装 (2)如果没安装 sudo apt-get install tftpd-hpa sudo apt-get install tf ...

  4. USACO 3.3 Riding the Fences

    Riding the Fences Farmer John owns a large number of fences that must be repaired annually. He trave ...

  5. 转:iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解

    1. autoResizing autoresizing是苹果早期的ui布局适配的解决办法,iOS6之前完全可以胜任了,因为苹果手机只有3.5寸的屏幕,在加上手机app很少支持横屏,所以iOS开发者基 ...

  6. MVC之联动学习

    一,数据库表设计 CREATE TABLE [dbo].[HY_Province]( [id] [INT] NOT NULL, [province] [NVARCHAR]() NOT NULL, CO ...

  7. linux(x64)下安装Matlab 2015b破解版(含安装包)

    注意:在安装前请查看安装目录是否有足够空间!完全安装大概需要12G的空间!本人在安装后系统盘满了,导致无法启动图形界面.小伙伴们不要重蹈覆辙~ Environment Linux debian8 (x ...

  8. ansible role 执行顺序

    the dependencies of the 'openshift-master' role.- docker- openshif_common  - os_firewall   - openshi ...

  9. Java定时任务器

    java定时任务,每天定时执行任务.以下是这个例子的全部代码. public class TimerManager { //时间间隔 private static final long PERIOD_ ...

  10. android教学大纲

    android班 教学大纲 个小时 次课:Android开发环境搭建及工具介绍 Android系统简介 Android开发环境简介及搭建 AndroidStudio提供的工具组件 次课:第一个Andr ...