CFRunLoop示例总结

来源:互联网 发布:淘宝客服电话沟通技巧 编辑:程序博客网 时间:2024/05/18 00:32

首先看两个runloop的示例


第一个:

  1. #include <CoreFoundation/CoreFoundation.h>  
  2.   
  3. static void  
  4. _perform(void *info __unused)  
  5. {  
  6.     printf("hello\n");  
  7. }  
  8.   
  9. static void  
  10. _timer(CFRunLoopTimerRef timer __unused, void *info)  
  11. {  
  12.     CFRunLoopSourceSignal(info);  
  13. }  
  14.   
  15. int  
  16. main()  
  17. {  
  18.     CFRunLoopSourceRef source;  
  19.     CFRunLoopSourceContext source_context;  
  20.     CFRunLoopTimerRef timer;  
  21.     CFRunLoopTimerContext timer_context;  
  22.   
  23.     bzero(&source_context, sizeof(source_context));  
  24.     source_context.perform = _perform;  
  25.     source = CFRunLoopSourceCreate(NULL, 0, &source_context);  
  26.     CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);  
  27.   
  28.     bzero(&timer_context, sizeof(timer_context));  
  29.     timer_context.info = source;  
  30.     timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 1, 0, 0, 
  31.     _timer, &timer_context);  
  32.     CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);  
  33.   
  34.     CFRunLoopRun();  
  35.   
  36.     return 0;  
  37. }  

第二个:

  1. #include <dispatch/dispatch.h>  
  2. #include <stdio.h>  
  3.   
  4. int  
  5. main()  
  6. {  
  7.     dispatch_source_t source, timer;  
  8.   
  9.     source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0,
  10.     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));  
  11.     dispatch_source_set_event_handler(source, ^{  
  12.         printf("hello\n");  
  13.     });  
  14.     dispatch_resume(source);  
  15.   
  16.     timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, 
  17.     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));  
  18.     dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1ull * NSEC_PER_SEC, 0);  
  19.     dispatch_source_set_event_handler(timer, ^{  
  20.         dispatch_source_merge_data(source, 1);  
  21.     });  
  22.     dispatch_resume(timer);  
  23.   
  24.     dispatch_main();  
  25. }  


功能是向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方法就不能触发。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 经常卡1无服务怎么办 华为手机进水无服务怎么办 苹果手机进水后无服务怎么办 苹果6进水无服务怎么办 华为手机突然无服务怎么办 sim卡显示无服务怎么办 华为麦芒进水无限开关机怎么办 华为麦芒5进水黑屏怎么办 华为麦芒6进水了怎么办 4g手机开不开机怎么办 全屏钢化膜总是翘边怎么办 华为麦芒屏幕触屏失灵怎么办 华为麦芒5运行慢怎么办 手机屏保密码忘记了怎么办 麦芒5密码锁忘了怎么办 超薄手机壳松了怎么办 华为麦芒5声音小怎么办 笔记本外壳a面裂了怎么办 苹果手机外壳摔坏了怎么办 挂衣服肩膀出包怎么办 摩拜单车手机号注销了怎么办 摩拜单车手机号码换了怎么办 摩拜单车换手机号码打不开怎么办 摩拜单车丢了怎么办 摩拜单车忘锁了怎么办 透明手机壳粘指纹怎么办 tpu手机壳变黄了怎么办 0pp0手机声音小怎么办 橡胶皮套晒坏了怎么办 宝宝晚上吹空调发烧怎么办 玩手机手指尖疼怎么办 手机型号不支持微信运动怎么办 手腕向下压会疼怎么办 手腕韧带拉伤怎么办恢复快 华为手机用车载充电慢怎么办 华为麦芒6充电慢怎么办 oppo手机压弯了怎么办 麦芒5电池不耐用怎么办 华为7x照相模糊怎么办 华为麦芒6照相虚怎么办 荣耀8gps信号弱怎么办