作者: 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. 《CSS网站布局实录》学习笔记(二)

    第二章 XHTML与CSS基础 2.1 XHTML基础 XHTML是网页代码的核心内容,标准XHTML代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  2. WinAPI——谐振动的合成

    #include<Windows.h> #include<math.h> #define NUM 1000 #define PI 3.14159 LRESULT CALLBAC ...

  3. FTP链接mac

    mac下一般用smb服务来进行远程文件访问,但要用FTP的话,高版本的mac os默认关掉了,可以用如下命令打开: sudo -s launchctl load -w /System/Library/ ...

  4. PHP Calendar 函数

    PHP 5 Calendar 函数 函数 描述 cal_days_in_month() 针对指定的年份和历法,返回一个月中的天数. cal_from_jd() 把儒略日计数转换为指定历法的日期. ca ...

  5. php插入转义与查找转义

    //转义用于查找 function deepslashes($data) { //判断data表现形式 if(empty($data)) { return $data; } return is_arr ...

  6. Java前端Rsa公钥加密,后端Rsa私钥解密(目前还不支持中文加密解密,其他都行)

    Base64工具类,可以让rsa编码的乱码变成一串字符序列 package com.utils; import java.io.ByteArrayInputStream; import java.io ...

  7. Java反射 - 1(得到类对象的几种方法,调用方法,得到包下的所有类)

    通过反射获得对象的方法 准备工作: 有一个User类如下 package o1; /** * Created by yesiming on 16-11-19. */ public class User ...

  8. java加载配置文件

    有时候一些变量可能会变,但直接写在程序代码中不好,因为有时候需要改的时候要改动源代码,这时候可以使用配置文件来管理.比如数据库中的端口和密码. 1. 把.properties配置文件放在src目录下. ...

  9. poj1182 并查集

     题目连接:http://poj.org/problem?id=1182 基础并查集,需要维护与根节点关系,解析见代码: /* poj 1182 并查集 思路分析:让你分析这些话里面多少假的 只需要用 ...

  10. ACM中常用的C/C++函数

    只大概说明功能,具体用法请自行百度. C函数 memset:按字节填充地址空间 sscanf:从一个字符串中格式化读取变量 sprintf:将变量格式化写入字符串中 atoi:字符串转int atof ...