转自:http://www.cocoachina.com/iphonedev/sdk/2011/1111/3487.html
首先看两个runloop的示例,来源:http://paste.lisp.org/display/86524
第一个:
- #include <CoreFoundation/CoreFoundation.h>
- static void
- _perform(void *info __unused)
- {
- printf("hello\n");
- }
- static void
- _timer(CFRunLoopTimerRef timer __unused, void *info)
- {
- CFRunLoopSourceSignal(info);
- }
- int
- main()
- {
- 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();
- return 0;
- }
第二个:
- #include <dispatch/dispatch.h>
- #include <stdio.h>
- int
- main()
- {
- 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, ^{
- dispatch_source_merge_data(source, 1);
- });
- dispatch_resume(timer);
- dispatch_main();
- }
功能是向main线程中加入两个input source,一个是timer,一个是自定义input source,然后这个timer中触发自定义source,于是调用其回调方法。 在这儿timer触发source来调用回调方法,显得有点多此一举。但是在多线程开发当中,这就很有用了,我们可以把这个自定义的source加入到子线程的runloop中,然后在主线程中触发source,这样在子线程中就可以调用回调方法了。 这样做的好久是什么呀? 节约用电,因为runloop一般情况下是休眠的,只有事件触发的时候才开始工作。 这与windows下的waitforsingleobject有点类似, 与多线程中的信号量,事件也有些雷同。
上面说到的input source(输入源例)到底是什么呢?输入源样例可能包括用户输入设备(如点击button)、网络链接(socket收到数据)、定期或时间延迟事件(NSTimer),还有异步回调(NSURLConnection的异步请求)。然后我们对其进行了分类,有三类可以被runloop监控,分别是sources、timers、observers。
在苹果文档中对runloop有详细介绍,下面参考中有中文版。那文档中的代码关于NSPort的部份在iOS上是不行的,不过可以用其CF方法实现,在我的demo中有展示。
每一个线程都有自己的runloop, 主线程是默认开启的,创建的子线程要手动开启,因为NSApplication 只启动main applicaiton thread。
没有source的runloop会自动结束。
事件由NSRunLoop 类处理。
RunLoop监视操作系统的输入源,如果没有事件数据, 不消耗任何CPU 资源。
如果有事件数据,run loop 就发送消息,通知各个对象。
用 currentRunLoop 获得 runloop的 reference
给 runloop 发送run 消息启动它。
文档中介绍下面四种情况是使用runloop的场合:
1.使用端口或自定义输入源和其他线程通信
2.子线程中使用了定时器
3.cocoa中使用任何performSelector到了线程中运行方法
4.使线程履行周期性任务,(我把这个理解与2相同)
如果我们在子线程中用了NSURLConnection异步请求,那也需要用到runloop,不然线程退出了,相应的delegate方法就不能触发。
解决的方法参看:
http://www.cocoabyss.com/foundation/nsurlconnection-synchronous-asynchronous/
http://www.wim.me/nsurlconnection-in-its-own-thread/
参考:
http://www.wim.me/nsurlconnection-in-its-own-thread/
http://iphonedevelopmentbits.com/event-driven-multitasking-runloopssymbian-ios
相关推荐
默认情况下RunLoop运行在kCFRunLoopDefaultMode下,而当滑动tableView时,RunLoop切换到UITrackingRunLoop
iOS中多线程原理与runloop介绍
iOS开发学习之iOS多线程和RunLoop.pdf
读懂iOS两部分核心源码: runtime & runloop,是每个iOS开发的基本素养。
运行循环演示 iOS开发·RunLoop源码与用法完全解析(输入源,定时源,观察者,线程间通信,端口间通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage) 了解更多 简书地址:
ios 的事件循环的实现原理,介绍了runloop机制
ios tableView 利用run Loop 进行懒惰加载 很多人 不知道怎么利用runLoop 处理cell 我这个专门做了一个小demo 处理了一下 分享给 想学习的人
iOS底层大厂Runloop面试题
利用RunLoop监控卡顿的demo,对应博客:https://blog.csdn.net/dolacmeng/article/details/89343075
使用RunLoop优化tableView加载大量图片卡顿问题,可有效解决主线程阻塞问题
关于运行循环的官方文档翻译,文档讲述运行循环创建开启使用等内容
含字节跳动,美团,腾讯百度等大厂面试题,iOS基础,算法,多线程,Runloop,GCD,动画,数据结构,性能,UI等等20多套PDF,物超所值,升职加薪就靠它了!!!
iOS 拦截奔溃 使程序不在崩溃 使用Runloop起死回生 拦截崩溃信息 传到服务器
关于Runloop的学习心得,Runloop源码分析以及学习资料
Runtime-RunLoop-源码.rar
本课程主要讲解iOS开发的一些中高级原理性的知识,并结合实际代码应用分析。主要包括:内存管理、RunTime、RunLoop、GCD与多线程。 对原理的讲解会从源码分析的角度深入剖析,除录播的视频外,每章节还会配有相应的...
详细解释 RunLoop工作的很好的例子。
1.讲讲runLoop,项目中有用到吗? 2.runLoop内部实现逻辑? 3.runLoop和线程的关系? 4.timer和runLoop的关系? 5.程序中添加每3秒响应一次的NSTimer,当拖动tableview的时候timer可能无法响应要怎么解决? 6.runLoop...
1.讲讲runLoop,项目中有用到吗? 2.runLoop内部实现逻辑? 3.runLoop和线程的关系? 4.timer和runLoop的关系? 5.程序中添加每3秒响应一次的NSTimer,当拖动tableview的时候timer可能无法响应要怎么解决? 6.runLoop...