作者: xwang 
出处: http://www.cnblogs.com/xwang/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
- (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]运行。

[NSTimer schduledTimerWithTimeInterval: target:selector:userInfo:repeats];

此方法默认添加到当前NSRunLoop中

NSTimer *timer = [NSTimer timerWithTimeInterval: invocation:repeates:];

NSTimer *timer = [[NSTimer alloc] initWithFireDate:...];

 
创建timer  [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
此方法是手动定制一个timer添加到新建的RunLoop里面
注意 timer的释放
 
 

我们在使用NSTimer的时候,可能会接触到runloop的概念,下面是一个简单的例子:

 1 - (void)viewDidLoad
2 {
3 [super viewDidLoad];
4 // Do any additional setup after loading the view, typically from a nib.
5 NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1
6 target:self
7 selector:@selector(printMessage:)
8 userInfo:nil
9 repeats:YES];
10 }

这个时候如果我们在界面上滚动一个scrollview,那么我们会发现在停止滚动前,控制台不会有任何输出,就好像scrollView在滚动的时候将timer暂停了一样,在查看相应文档后发现,这其实就是runloop的mode在做怪。
runloop可以理解为cocoa下的一种消息循环机制,用来处理各种消息事件,我们在开发的时候并不需要手动去创建一个runloop,因为框架为我们创建了一个默认的runloop,通过[NSRunloop currentRunloop]我们可以得到一个当前线程下面对应的runloop对象,不过我们需要注意的是不同的runloop之间消息的通知方式。

接着上面的话题,在开启一个NSTimer实质上是在当前的runloop中注册了一个新的事件源,而当scrollView滚动的时候,当前的MainRunLoop是处于UITrackingRunLoopMode的模式下,在这个模式下,是不会处理NSDefaultRunLoopMode的消息(因为RunLoop Mode不一样),要想在scrollView滚动的同时也接受其它runloop的消息,我们需要改变两者之间的runloopmode.

1 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

简单的说就是NSTimer不会开启新的进程,只是在Runloop里注册了一下,Runloop每次loop时都会检测这个timer,看是否可以触发。当Runloop在A mode,而timer注册在B mode时就无法去检测这个timer,所以需要把NSTimer也注册到A mode,这样就可以被检测到。

说到这里,在http异步通信的模块中也有可能碰到这样的问题,就是在向服务器异步获取图片数据通知主线程刷新tableView中的图片时,在tableView滚动没有停止或用户手指停留在屏幕上的时候,图片一直不会出来,可能背后也是这个runloop的mode在做怪,嘿嘿。

 
 

NSRunLoop个人理解的更多相关文章

  1. NSRunLoop的利用

    一.NSRunLoop的理解        在初学C语言编程的时候,经常会写一种控制台中的程序,程序启动黑色的输入框,等待用户的输入,输入一组数据之后程序继续往下执行程序在等待用户输入数据时会阻塞,这 ...

  2. iOS NSRunloop的简单理解

    最近学习了下NSRunloop. 作一下简单的理解: 1.runloop与线程的关系,每一个线程创建是都会有伴有一个runloop诞生,runloop用来接收事件源,让线程执行事件.当没有事件处理时, ...

  3. NSRunLoop的进一步理解

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

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

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

  5. iOS开发之NSRunLoop的进一步理解

    http://www.cnblogs.com/pengyingh/articles/2343920.html iPhone应用开发中关于NSRunLoop的概述是本文要介绍的内容,NSRunLoop是 ...

  6. Cocoa深入学习:NSOperationQueue、NSRunLoop和线程安全 (转)

    目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD .其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实 ...

  7. NSRunLoop

    1.什么是RunLoop 运行循环 一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop得手动启动(调用run方法) RunLoop只能选择一个Mode启动,如果 ...

  8. 深入理解RunLoop

    网上看的一篇文章,写的真好,我得多看几次好好理解理解 膜拜大神,转载至此便于学习查看. 此处标明原文链接:http://blog.ibireme.com/2015/05/18/runloop/    ...

  9. [iOS]浅谈NSRunloop工作原理和相关应用

    一. 认识NSRunloop  1.1 NSRunloop与程序运行 那么具体什么是NSRunLoop呢?其实NSRunLoop的本质是一个消息机制的处理模式.让我们首先来看一下程序的入口——main ...

随机推荐

  1. Cors 跨域Access-Control-Allow-Origin

    1.Access-Control-Allow-Origin 指定格式 The Origin header field has the following syntax: origin = " ...

  2. 粗俗易懂的SQL存储过程在.NET中的实例运用

    整理了一下存储过程在项目中的运用,防止遗忘,便记录于此!存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中.用户通过指定存储过程的名字并给出参数( ...

  3. android studio 改变主题及字体大小

    一丶修改主题背景 1.点击图中的小扳子图标(设置),或者点击file->setting-> 2.找到Appearance->在Theme中选择Darcula,即可改变成当前最主流的主 ...

  4. 星座物语APP

    效果图: 这里的后台管理用的是duducat,大家可以去百度看说明.图片,文字都在duducat后台服务器上,可以自己修改的.(PS:图片这里是随便找的) http://www.duducat.com ...

  5. C# 连接SQL数据库

    感觉很有必要总结一下 一:C# 连接SQL数据库 Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;P ...

  6. java BigDecimal的操作

    今天给大家讲一下java中BigDecimal的操作.由于double,float的精度不够,因此在进行商业计算的时候要使用的BigDecimal.BigDecimal对象创建如下: BigDecim ...

  7. PHP 运算符

    本章节我们将讨论 PHP 中不同运算符的应用. 在 PHP 中,赋值运算符 = 用于给变量赋值. 在 PHP 中,算术运算符 + 用于把值加在一起. PHP 算术运算符 运算符 名称 描述 实例 结果 ...

  8. decode()与case then 学习与使用

    今天做项目的时候遇到一个oracle数值转换的问题,按需求需要对匹配系统时间进行固定赋值,为了避免增加复杂度并易于维护,尽量不要使用存储过程或触发器,最好是使用oracle 自带函数. 如: SQL& ...

  9. 带格式导出数据到Excel

    导出按钮事件 protected void Button1_Click(object sender, EventArgs e)    {        Response.Clear();        ...

  10. web页面相关的一些常见可用字符介绍

    首先是一张图片,是一张一些字符以及想对应的HTML实体表示的对照图片.如下: 一.引号模样或内心的些字符 请选择该表格要呈现的字体: 字符以及HTML实体 描述以及说明 " " 这 ...