iOS-消息循环RunLoop详解

摘要:
二、RunLoop的概念和功能概念:一般来说,一个线程一次只能执行一个任务,线程在执行后会退出。例如,如果一个应用程序放在那里而不运行,那么它就像在休息。单击该按钮将做出响应,就像“随叫随到”一样。这是RunLoop的功劳。所以RunLoop实际上是一个对象,它管理需要处理的事件和消息,并提供一个入口函数来执行RunLoop的逻辑。可以说,没有线程,就不需要RunLoop。

RunLoop,跑圈。在iOS开发中,也就是运行循环。

在应用需要的时候自己跑起来运行,在用户没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。

. RunLoop的概念与作用

概念:一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的任务。

例如一个应用放那里,不进行操作就像静止休息一样,点击按钮,就有响应,就像“随时待命”一样,这就是RunLoop的功劳。

所以RunLoop实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行RunLoop的逻辑。

线程开始这个函数之后,便一直会处于此函数 "接受消息->等待->处理" 的循环中:(有事:做出反应; 木事:休眠省电; 再次有事:重新唤醒、处理事件。)

直到这个循环结束(比如传入 quit 的消息),最后函数返回。

作用:

  1. 保持程序持续运行:例如程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop,RunLoop保证主线程不会被销毁,也就保证了程序的持续运行;
  2. 处理App中的各种事件(比如:触摸事件,定时器事件,Selector事件等 );
  3. 节省CPU资源,优化程序性能:程序运行起来时,当什么操作都没有做的时候,RunLoop就通知系统,现在没有事情做,然后进行休息待命状态,这时系统就会将其资源释放出来去做其他的事情。当有事情做,也就是一有响应的时候RunLoop就会立马起来去做事情;

RunLoop,最重要的作用,也就是用来管理线程的。可以说,没有线程,也就没有RunLoop的存在必要。

当线程的RunLoop一开启,RunLoop便开始对线程进行管理工作:在线程执行完任务后,线程便会进入休眠状态,并且不会退出,随时等待新的任务。

三、RunLoop与线程的关系

1.每条线程都有唯一的一个与之对应的RunLoop对象;

2.RunLoop在第一次获取时创建,在线程结束时销毁;只能在一个线程的内部获取其 RunLoop(主线程除外)。

3.主线程的RunLoop系统默认启动,子线程的RunLoop需要主动开启;

其实在我们每次建立项目的时候,就已经使用上了RunLoop。

(这里只是粗略的知识点,主要的看下面截图)
只有主线程的消息循环默认开启,子线程的消息循环默认不开启
(个人理解) 每一个输入源或定时源都必须对应一个模式(只有与消息循环的模式对应上了,,这里的定时源才会执行)
消息循环是在一个指定的模式下运行的 默认的模式NSDefaultRunLoopMode,设置的输入事件也需要指定一个模式,消息循环的模式必须和输入事件的模式匹配才会执行
UITrackingRunLoopMode 当滚动scrollView的时候,消息循环的模式会改变成这种
使用消息循环的时候必须指定两件事情
1 . 输入事件:输入源和定时源
2 . 消息循环的模式
eg:
// 这里的self,是selector里面的方法的所属对象
// userInfo 是方法跟的参数
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES];
//把定时器添加到当前线程消息循环中 这个就是定时源的模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
currentRunLoop 当前的消息循环吧
***********
- (void)demo {
//输出当前消息循环的模式
NSLog(@"%@",[NSRunLoop currentRunLoop].currentMode);
}

#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 这里的self,是selector里面的方法的所属对象
// userInfo 是方法跟的参数
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES];
//把定时器添加到当前线程消息循环中 这个就是定时源的模式
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
// (个人理解) 每一个输入源或定时源都必须对应一个模式(只有与消息循环的模式对应上了,,这里的定时源才会执行)
//消息循环是在一个指定的模式下运行的 默认的模式NSDefaultRunLoopMode,设置的输入事件也需要指定一个模式,消息循环的模式必须和输入事件的模式匹配才会执行
//UITrackingRunLoopMode 当滚动scrollView的时候,消息循环的模式会改变成这种
}
- (void)demo {
//输出当前消息循环的模式
NSLog(@"hello %@",[NSRunLoop currentRunLoop].currentMode);
}
@end

免责声明:文章转载自《iOS-消息循环RunLoop详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VSCode插件开发全攻略(九)常用API总结iOS 开发之照片框架详解(3)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ABP框架 UnitOfWorkAttribute

记录下: 使用Castle.DynamicProxy实现动态代理   参考项目地址:https://github.com/f135ta/SimpleProxy   要点:     方法上的 Attribute 与 对应的拦截器一一对应     具体的Proxy由Castle.DynamicProxy实现 创建UnitOfWork   1.由IUnitOfW...

C# 线程手册 第二章 .NET 中的线程 终止/等待线程

Abort()方法可以用来终止当前线程。不论何种情况下你想终止线程,比如线程执行了太长时间或者用户取消了之前的决定,Abort()方法都很重要。在一个花费很长时间的搜索进程中你可能想使用这个方法。一个搜索引擎可能在继续运行但是用户已经看到了他们想要的结果,所以用户会终止搜索引擎所运行的线程。当在一个线程外调用Abort()方法时,会引发一个ThreadAb...

Java面试——多线程面试题总结

0.前言 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分,本文汇总了常见的一些多线程面试题。 一些问题,比如volatile关键词的作用,synchronized和ReentrantLock的区别,wait()和sleep()的区别等等问题,已经在之前写过的文章中提到过了,这里就不赘述了,有兴趣可以查看以下几篇文章:Java并发——线程同...

使用 VisualVM 进行性能分析及调优

VisualVM 是一款免费的集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。本文主要介绍如何使用 VisualVM 进行性能分析及调优。   概述 开发大...

Java多线程基础:进程和线程之由来

  在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程。当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通使用的,需要在实践中不断积累。由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助。   下面是本文的目录大纲:  ...

notify()和notifyAll()有什么区别?

先解释两个概念。 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁。 锁池:只有获取了对象的锁,线程才能执行对象的 synchronized 代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待 区别: notify() 方法随机唤醒对象的等待池中...