今天看到了NSRunloop,其实之前也有看了关于NSRunloop的内容,在这里想简单的就个人的理解总结一下。其实自己在开发的过程当中,还没有更多的涉及到NSRunloop的功能。总的来说,NSRunloop就是类似于windows的消息机制。他的存在是给线程增加事件处理机制。

对于多线程开发而言,有两种处理方案,一种是不需要太多的交互,直接运算比较大的数据内容就可以,另一种方法是将执行函数加入到消息循环当中去,等待事件的发生,然后执行。

有了NSRunloop,会使线程的表现变得更加的好,他的存在一个重要目的是当有事件发生时,唤醒线程,当没有事件时,线程将处于休眠状态,这样的多线程运行,用户表现会非常的好。因为,线程其实也是有开销的。

对于NSRunloop来说,他的输入原,有事件输入原和定时器,事件输入原是异步通信的方式,而定时器是同步的输入方式。对于事件输入原,其实并不是用户直接定义的,而是通过一些特定的port对象机器方法共同实现的。

Run loops 是线程相关的的基础框架的一部分。一个 run loop 就是一个事件处理 的循环,用来不停的调度工作以及处理输入事件。使用 run loop 的目的是让你的线 程在有工作的时候忙于工作,而没工作的时候处于休眠状态。

Run loops 是线程相关的的基础框架的一部分。一个 run loop 就是一个事件处理 的循环,用来不停的调度工作以及处理输入事件。使用 run loop 的目的是让你的线 程在有工作的时候忙于工作,而没工作的时候处于休眠状态。

何时使用Runloop

3.2 何时使用 Run Loop

仅当在为你的程序创建辅助线程的时候,你才需要显式运行一个 run loop。Run loop 是程序主线程基础设施的关键部分。所以,Cocoa 和 Carbon 程序提供了代码运 行主程序的循环并自动启动 run loop。IOS 程序中 UIApplication 的 run 方法(或 Mac OS X 中的 NSApplication)作为程序启动步骤的一部分,它在程序正常启动的时 候就会启动程序的主循环。类似的,RunApplicationEventLoop 函数为 Carbon 程序 启动主循环。如果你使用 xcode 提供的模板创建你的程序,那你永远不需要自己去显 式的调用这些例程。

对于辅助线程,你需要判断一个 run loop 是否是必须的。如果是必须的,那么 你要自己配置并启动它。你不需要在任何情况下都去启动一个线程的 run loop。比 如,你使用线程来处理一个预先定义的长时间运行的任务时,你应该避免启动 run loop。Run loop 在你要和线程有更多的交互时才需要,比如以下情况:

 使用端口或自定义输入源来和其他线程通信  使用线程的定时器  Cocoa 中使用任何 performSelector...的方法 使线程周期性工作

一、RunLoop的使用示例

1、

#import <UIKit/UIKit.h>

#import <CoreFoundation/CoreFoundation.h>

#import "AppDelegate.h"

static void _perform(void *info __unused)

{

printf("hello\n");

}

static void _timer(CFRunLoopTimerRef timer __unused, void *info)

{

CFRunLoopSourceSignal(info);

}

int main(int argc, char *argv[])

{

@autoreleasepool {

CFRunLoopSourceRef source;

CFRunLoopSourceContext source_context;

CFRunLoopTimerRef timer;

CFRunLoopTimerContext timer_context;

bzero(&source_context, sizeof(source_context));

source_context.perform = _perform;

source = CFRunLoopSourceCreate(NULL, 0, &source_context);

CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);

bzero(&timer_context, sizeof(timer_context));

timer_context.info = source;

timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 1, 0, 0, _timer, &timer_context);

CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);

CFRunLoopRun();

returnUIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegateclass]));

}

}

2、

#import <UIKit/UIKit.h>

#import <stdio.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])

{

@autoreleasepool {

dispatch_source_t source, timer;

source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));

dispatch_source_set_event_handler(source, ^{

printf("hello\n");

});

dispatch_resume(source);

timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));

dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC, 0);

dispatch_source_set_event_handler(timer, ^{

     printf("world\n");

dispatch_source_merge_data(source, 1);

});

dispatch_resume(timer);

dispatch_main();

returnUIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegateclass]));

}

}

两个示例的功能是:

在主线程中加入两个input source, 一个是timer ,另一个是自定义input source .

在timer中触发自定制的input source;然后在input source 中触发timer.相互回调。

在多线程的开发中,把这个自定义的source加入到子线程的runloop中,然后在主线程中触发source,

runloop一般情况下是休眠的,只有事件触发的时候才开始工作。节省资源。

input source(输入源):输入源可以是用户输入设备(如点击button)、网络链接(socket收到数据)、

定期或时间延迟事件(NSTimer),还有异步回调(NSURLConnection的异步请求)。

然后我们对其进行了分类,有三类可以被runloop监控,分别是sources、timers、observers。

每一个线程都有自己的runloop, 主线程是默认开启的,创建的子线程要手动开启,因为NSApplication 只启动main applicaiton thread。

没有source的runloop会自动结束。

事件由NSRunLoop 类处理。

RunLoop监视操作系统的输入源,如果没有事件数据, 不消耗任何CPU 资源。

如果有事件数据,run loop 就发送消息,通知各个对象。

用 currentRunLoop 获得 runloop的 reference

给 runloop 发送run 消息启动它。

使用runloop的四种场合:

1.使用端口或自定义输入源和其他线程通信

2.子线程中使用了定时器

3.cocoa中使用任何performSelector到了线程中运行方法

4.使线程履行周期性任务

如果我们在子线程中用了NSURLConnection异步请求,那也需要用到runloop,不然线程退出了,相应的delegate方法就不能触发。

解决的方法参看:

http://www.cocoabyss.com/foundation/nsurlconnection-synchronous-asynchronous/

http://www.wim.me/nsurlconnection-in-its-own-thread/

NSRunLoop 详解的更多相关文章

  1. NSRunLoop详解

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

  2. iOS中-Qutarz2D详解及使用

    在iOS中Qutarz2D 详解及使用 (一)初识 介绍 Quartz 2D是二维绘图引擎. 能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成 ...

  3. iOS开发——UI篇&ScrollView详解

    创建方式 1:StoryBoard/Xib 这里StoarBoard就不多说,直接拖就可以,说太多没意思,如果连这个都不会我只能先给你跪了! 2:代码: CGRect bounds = [ [ UIS ...

  4. ScrollView详解

    创建方式 1:StoryBoard/Xib 这里StoarBoard就不多说,直接拖就可以,说太多没意思,如果连这个都不会我只能先给你跪了! 2:代码: 1 2 3 CGRect bounds = [ ...

  5. Objective-C之run loop详解

    Objective-C之run loop详解 做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一门语言还是需要深 ...

  6. 《招一个靠谱的移动开发》iOS面试题及详解(下篇)

    iOS面试知识点 现在进入本篇的正题.本篇的面试题是我认为比较好的iOS开发基础知识点,希望大家看过这后在理解的基础上掌握而不是死记硬背.死记硬背很快也会忘记的. 1 iOS基础 1.1 父类实现深拷 ...

  7. 《招一个靠谱的移动开发》iOS面试题及详解(上篇)

    以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...

  8. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  9. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

随机推荐

  1. 官方recovery签名验证的破解教程

    下面讲如何破解官方recovery签名验证(这个方法应该是通用的,其他手机可以参考,recovery签名验证破解了,也不用费力编译第三方recovery) 1.从官方ROM里提取recovery.im ...

  2. KEIL中的变量相关

    例:sfr P0=0x80表示P0口地址为80H:(sfr是字节操作) sfr16 T2=0xCC表示T2口地址的低地址为TL2=0XCC,高地址为TH2=0XCD(sfr16是字操作) 头文件reg ...

  3. vs2010 suite integration toolkit execution

    原因是UltraDeamen的问题,重新换个WinMount来解压ISO文件.完美安装运行

  4. jQuery的animate方法在IE8下出现小问题

    今天修改网站的bug,把网页显示的几张图片给做成左右滑动的动画效果: 由于本身有一个demo可供参考,然后在此基础上进行修改,所以很快就搞定了,然后在chrome,firefox,IE9下分别进行测试 ...

  5. bzoj4003

    http://www.lydsy.com/JudgeOnline/problem.php?id=4003 可合并堆. 每个点都有一个小根堆,记住可以到这个点的骑士有哪些,以战斗力为关键字. 从底层到顶 ...

  6. Python闭包与函数对象

    1. Python闭包是什么 在python中有函数闭包的概念,这个概念是什么意思呢,查看Wikipedia的说明如下: “ In programming languages, closures (a ...

  7. MYSQL查询男女数量的存储过程

    存储过程代码: BEGIN IF sex_id =0 THEN SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='女' INTO sex_co ...

  8. SRM 588 D2 L3:GameInDarknessDiv2,DFS

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12710 采用DFS搜索,第一次写的时候忘了加访问标志,结果状态 ...

  9. HDU--1584--蜘蛛牌--深搜版本号

    蜘蛛牌 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  10. ARM指令集——数据处理指令

    ARM汇编指令集 ARM汇编文件的组成 指令:编译完成后作为一条指令(机器码)存储在内存单元中,CPU执行时能够完成处理的操作 伪指令:在编译时替换成能被识别的ARM指令 伪操作:知道编译器进行编译, ...