`
亚当爱上java
  • 浏览: 707220 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

NSRunLoop概述和原理[转]

 
阅读更多
1.什么是NSRunLoop?
我们会经常看到这样的代码:

- (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]运行。这样做就显得简介,而且逻辑很清晰。如果你不这样做,你就需要在loadPageInBackground里面表示load完成的地方调用[progress setHidden:YES],显得代码不紧凑而且容易出错。
那么具体什么是NSRunLoop呢?其实NSRunLoop的本质是一个消息机制的处理模式。如果你对vc++编程有一定了解,在windows中,有一系列很重要的函数SendMessage,PostMessage,GetMessage,这些都是有关消息传递处理的API。但是在你进入到Cocoa的编程世界里面,我不知道你是不是走的太快太匆忙而忽视了这个很重要的问题,Cocoa里面就没有提及到任何关于消息处理的API,开发者从来也没有自己去关心过消息的传递过程,好像一切都是那么自然,像大自然一样自然?在Cocoa里面你再也不用去自己定义WM_COMMAD_XXX这样的宏来标识某个消息,也不用在switch-case里面去对特定的消息做特别的处理。难道是Cocoa里面就没有了消息机制?答案是否定的,只是Apple在设计消息处理的时候采用了一个更加高明的模式,那就是RunLoop。

2. NSRunLoop工作原理
接下来看一下NSRunLoop具体的工作原理,首先是官方文档提供的说法,看图:



通过所有的“消息”都被添加到了NSRunLoop中去,而在这里这些消息并分为“input source”和“Timer source” 并在循环中检查是不是有事件需要发生,如果需要那么就调用相应的函数处理。为了更清晰的解释,我们来对比VC++和iOS消息处理过程。

VC++中在一切初始化都完成之后程序就开始这样一个循环了(代码是从户sir mfc程序设计课程的slides中截取):


 int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR  lpCmdLine,int nCmdShow){
...
while (GetMessage(&msg, NULL, 0, 0)){
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
} 


可以看到在GetMessage之后就去分发处理消息了,而iOS中main函数中只是调用了UIApplicationMain,那么我们可以介意猜出UIApplicationMain在初始化完成之后就会进入这样一个情形:

int UIApplicationMain(...){
...
while(running){
[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
...
} 


所以在UIApplicationMain中也是同样在不断处理runloop才是的程序没有退出。刚才的我说了NSRunLoop是一种更加高明的消息处理模式,他就高明在对消息处理过程进行了更好的抽象和封装,这样才能是的你不用处理一些很琐碎很低层次的具体消息的处理,在NSRunLoop中每一个消息就被打包在input source或者是timer source中了,当需要处理的时候就直接调用其中包含的相应对象的处理函数了。所以对外部的开发人员来讲,你感受到的就是,把source/timer加入到runloop中,然后在适当的时候类似于[receiver action]这样的事情发生了。甚至很多时候,你都没有感受到整个过程前半部分,你只是感觉到了你的某个对象的某个函数调用了。比如在UIView被触摸时会用touchesBegan/touchesMoved等等函数被调用,也许你会想,“该死的,我都不知道在那里被告知有触摸消息,这些处理函数就被调用了!?”所以,消息是有的,只是runloop已经帮你做了!为了证明我的观点,我截取了一张debug touchesBegan的call stack,有图有真相:



  • 大小: 49.7 KB
  • 大小: 36.5 KB
分享到:
评论

相关推荐

    ios 事件循环原理-runloop

    本文将深入探讨 NSRunLoop 的工作原理和实现机制。 一、什么是 NSRunLoop? NSRunLoop 是一种高明的消息处理模式,它对消息处理过程进行了抽象和封装,使得开发者不需要关心具体的消息处理过程。在 NSRunLoop 中,...

    也来谈谈CFRunLoop(NSRunLoop)

    CFRunLoop(NSRunLoop)是苹果操作系统中的核心组件,主要用于处理事件循环和线程调度,尤其在iOS和Mac OS X的应用程序开发中起着至关重要的作用。这篇文章将深入探讨这两个概念,以及它们在实际开发中的应用。 ...

    NSRunLoopDemo

    综上所述,`NSRunLoopDemo`提供了丰富的示例,帮助开发者深入理解`NSRunLoop`的工作原理及其在实际开发中的应用。通过学习这个项目,你可以掌握如何有效地使用`NSRunLoop`来提升应用程序的性能和用户体验。

    LightWeightRunLoop-A-Reactor-Style-NSRunLoop, NSRunLoop反应器样式实现.zip

    LightWeightRunLoop-A-Reactor-Style-NSRunLoop, NSRunLoop反应器样式实现 LightWeightRunLoop在其他线程,定时器,URLConnection,LWStream ( LWInputStream、LWOutputStream ),LWPort ( LWSocketPort ) 等上实现 ...

    RunLoop例子

    Run Loop的配置和管理可以通过Objective-C的CFRunLoopRef(Core Foundation层)和NSRunLoop(Foundation层)进行。开发者可以通过添加源(Sources)、观察者(Observers)和端口(Ports)来定制Run Loop的行为,例如...

    Cocoa基本原理指南

    Cocoa通过核心对象,如应用对象(NSApplication)、窗口对象(NSWindow)和事件循环(NSRunLoop)等,来管理应用程序的生命周期和处理用户交互。这种架构为开发者提供了清晰的应用程序运行机制,使得开发者能够专注...

    RunLoop示例

    在iOS和macOS开发中,`NSRunLoop`是苹果操作系统中的一个核心组件,它负责处理应用程序的事件循环,保持程序的运行并响应用户输入。`NSRunLoop`与`NSThread`和`Dispatch Queue`紧密相关,它们都是Apple的多线程编程...

    ConcurrentCource

    在IT行业中,并发编程是构建高性能、高效率应用的关键技术之一。在iOS和macOS开发中,Objective-C作为主要的编程语言,提供了...同时,理解并发编程背后的原理和最佳实践,也是提升软件质量,避免线程安全问题的关键。

    DispatchSourceTest.zip

    `NSThread`、`NSRunLoop`和`Dispatch Queue`是Apple的Foundation框架中用于多线程和异步任务处理的关键组件。本篇文章将深入探讨这三个概念,并通过`DispatchSourceTest.zip`中的示例代码来具体说明它们的用法。 ...

    Addison.Wesley.Learning.ObjectiveC.2.0.Jul.2010.rar

    理解GCD的工作原理和API,能帮助开发者编写出高效、线程安全的代码。 9. **NSRunLoop**:NSRunLoop是事件驱动编程的核心,用于处理应用的事件循环。理解NSRunLoop的工作方式对于处理长时间运行的任务和保持应用响应...

    7.多线程篇1

    NSRunLoop允许应用在没有用户交互时保持活动状态,以便能够及时响应各种输入源和定时器。 - A. NSRunLoop的基本使用:通过`[[NSRunLoop mainRunLoop] runUntilDate:]`或`[[NSRunLoop mainRunLoop] run]`启动运行...

    IOS面试题总结,集合了很多培训机构的老师精心整理出来的,绝对给力

    - 对象的内存管理,包括ARC(Automatic Reference Counting)的工作原理。 - KVC(Key-Value Coding)和KVO(Key-Value Observing)。 - Category和Extension的使用场景。 2. **Swift语言特性** - Swift的基本...

    Objective-C培训PPT,非常详细全面,没有logo,有配套代码

    Objective-C使用引用计数进行内存管理,这部分可能涵盖`retain`、`release`、`autorelease`,以及ARC(Automatic Reference Counting)自动引用计数的原理和使用。 6. **6 文件管理.ppt**: 文件管理在iOS应用中...

    dns library for objective c.zip

    在IT行业中,DNS(Domain Name System)是...如果库没有文档,开发者可能需要通过查看源代码和示例来学习其工作原理。在实际项目中,正确地集成和配置DNS库,以及处理可能的异常情况,都是成功应用开发的关键步骤。

    【叶-孤-城】iOS进阶指南

    掌握NSRunLoop的工作原理有助于更好地理解消息传递和线程间的通信。 1. **模式(Modes)**:了解不同模式下的事件处理方式。 2. **输入源(Sources)**:学习如何向RunLoop添加自定义的输入源。 3. **定时器...

    简单的时间选择器Nstimer

    `NSTimer`是`NSRunLoop`的一部分,它不直接运行在主线程上,而是依赖于运行循环(`NSRunLoop`)来安排和触发事件。创建`NSTimer`时,我们需要指定间隔时间、重复次数、以及一个selector(方法名),当定时器触发时,...

    06-应用程序1

    - **多线程中的NSRunLoop**:主线程默认配置了NSRunLoop,而子线程需要根据需求手动配置和启动。如果子线程需要处理异步事件或维持长时间运行,就需要运行NSRunLoop;反之,仅用于一次性任务的线程则无需启动。 4....

    Nsrun loop test

    本文将深入探讨消息循环的基本原理、工作方式以及如何通过编程实现。我们将以"Nsrun loop test"为例,这是一个简单的示例,帮助我们理解消息循环的工作机制。 消息循环是操作系统和应用程序之间进行通信的一种机制...

    Objective-C高级编程 iOS与OS X多线程和内存管理

    4. **NSRunLoop**:在线程中管理事件循环,确保线程不会立即退出,而是等待接收事件。 5. **NSInvocationOperation**和`NSInvocation`:基于`NSOperation`的轻量级多线程解决方案,可以将方法封装为操作进行异步...

    Runtime-RunLoop-源码.rar

    苹果提供了两种主要的 RunLoop 类型:CFRunLoop(Core Foundation)和 NSRunLoop(Foundation),它们之间通过桥接协议互通。 1. RunLoop 结构与工作原理 RunLoop 包含多个模式(Mode),每个模式下又包含若干个源...

Global site tag (gtag.js) - Google Analytics