`

iOS运行回路(RunLoop)总结

 
阅读更多

转自:http://www.cocoachina.com/iphonedev/sdk/2011/1111/3487.html

 

首先看两个runloop的示例,来源:http://paste.lisp.org/display/86524

第一个:

 

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

解决的方法参看:

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

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

 

参考:

http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

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

http://xubenyang.me/384

http://iphonedevelopmentbits.com/event-driven-multitasking-runloopssymbian-ios

分享到:
评论

相关推荐

    iOSputao#iOS-#RunLoop与NSTimer1

    默认情况下RunLoop运行在kCFRunLoopDefaultMode下,而当滑动tableView时,RunLoop切换到UITrackingRunLoop

    iOS Objective-C Runtime v723 & Runloop 打包源码

    在iOS开发中,Objective-C Runtime和RunLoop是两个至关重要的概念,它们构成了系统运行的基础,并对应用性能和用户体验有着深远的影响。下面将详细解释这两个概念及其源码中的关键知识点。 Objective-C Runtime是...

    在iOS程序发生崩溃时,通过Runloop循环执行,达到挽救不被崩溃,友好的返回首

    在iOS程序发生崩溃时,通过Runloop循环执行,达到挽救不被崩溃,友好的返回首页的目的(免被产品_RunloopCrashSaveDemo

    iOS中多线程原理与runloop介绍

    ### iOS中多线程原理与runloop介绍 #### 一、线程概述 在iOS开发中,线程是构成程序的基本单位之一。一个程序至少包含一个线程——主线程(Main Thread),它负责应用程序的主要逻辑及用户界面的绘制。主线程在iOS...

    ios tableView 利用run Loop

    RunLoop是iOS中的一个核心概念,它负责处理应用程序的事件循环,确保程序在没有用户交互时仍能保持运行状态。RunLoop的主要职责是接收事件、调度线程并管理它们的生命周期。在UITableView中,我们可以利用RunLoop来...

    iOS开发学习之iOS多线程和RunLoop.pdf

    RunLoop是iOS和Mac OS中的核心组件,它运行在一个线程中,用于监听和处理输入源。其主要职责是保持程序运行,它不会让线程退出。当没有更多的事件处理时,它会将线程置于睡眠状态。在开发中,我们经常需要操作...

    RunloopDemo:iOS开发·RunLoop源码与用法完全解析(输入源,定时源,观察者,线程间通信,端口间通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage)-源码解析

    运行循环演示 iOS开发·RunLoop源码与用法完全解析(输入源,定时源,观察者,线程间通信,端口间通信,NSPort,NSMessagePort,NSMachPort,NSPortMessage) 了解更多 简书地址:

    利用RunLoop监控卡顿

    在iOS开发中,RunLoop是苹果提供的一种机制,用于管理应用程序的事件处理和线程调度。本文将深入探讨如何利用RunLoop来监控应用中的卡顿问题,同时结合提供的`HYRunLoopDemo`进行实例分析。 首先,我们需要了解...

    RunLoop demo

    总结来说,RunLoop是iOS和macOS开发中的重要组件,它管理了应用程序的事件处理和线程调度。通过分析`RunLoop很好的例子`这个项目,开发者可以更深入地了解RunLoop的工作机制,并学会如何在实际项目中有效利用它来...

    ios 事件循环原理-runloop

    iOS 事件循环原理-Run Loop 在 iOS 开发中,事件循环机制扮演着至关重要的角色,其中 NSRunLoop 是一个核心组件,负责管理和处理事件。本文将深入探讨 NSRunLoop 的工作原理和实现机制。 一、什么是 NSRunLoop? ...

    RunLoop优化tableView加载大量图片卡顿问题

    在主线程中,RunLoop默认被创建并运行,使得UI能够持续响应用户交互。在UITableView的滚动过程中,如果在主线程中加载图片,会占用大量CPU资源,导致RunLoop无法及时处理其他事件,从而出现卡顿现象。 针对这个问题...

    Runtime-RunLoop-源码.rar

    在 iOS 和 macOS 开发中,RunLoop 是一个至关重要的概念,它在程序运行过程中起到了调度和管理的作用。本文将深入探讨 RunLoop 的内部机制,帮助开发者理解其工作原理,从而更好地优化应用程序的性能。 RunLoop,...

    iOS各类面试题总结.zip

    这份名为"IOS各类面试题总结.zip"的压缩包文件包含了针对iOS开发者的全面面试准备资料。其中涵盖了多个知名互联网大厂如字节跳动、美团、腾讯和百度的面试题目,旨在帮助iOS开发者提升技能,顺利通过面试,实现职业...

    swift-关于Runloop的学习心得Runloop源码分析以及学习资料

    Runloop,直译为“运行循环”,是Apple操作系统(包括iOS和macOS)中的一种机制,用于管理应用程序的线程,确保它们在没有事件处理时能够进入休眠状态,从而节省系统资源。本文将深入探讨Runloop的工作原理、使用...

    RunLoop-线程保活.zip

    RunLoop是iOS和macOS开发中的一个重要概念,它与线程管理息息相关,特别是在处理长时间运行的任务或者维护线程活跃状态时显得尤为重要。本文将深入探讨RunLoop的原理、作用以及如何利用RunLoop来保持线程的活性。 ...

    ios高级经典面试

    本文将详细探讨iOS面试中关于Runloop的知识点。 Runloop是iOS开发中的核心概念之一,它负责监听和处理事件。在iOS和macOS系统中,每个线程,包括主线程,都有一个与之相关联的Runloop对象,它使得线程能够在没有...

    iOS 拦截奔溃 使程序不在崩溃

    本文将详细介绍如何在iOS中实现拦截奔溃,以及利用Runloop来防止应用意外关闭。 首先,我们需要理解什么是奔溃。在iOS中,应用程序通常因为执行了非法操作,如访问空指针、内存溢出或者调用不存在的方法等,而导致...

    一个runloop例子

    Runloop是iOS和macOS开发中的一个重要概念,它在Objective-C和Swift中被广泛使用,尤其是在处理多线程和事件循环时。Runloop是苹果操作系统内核提供的一个机制,用于管理应用程序的线程,特别是主线程。理解并合理...

Global site tag (gtag.js) - Google Analytics