zoukankan      html  css  js  c++  java
  • iOS-消息循环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
  • 相关阅读:
    【3】hexo+github搭建个人博客的主题配置
    【2】hexo+github搭建个人博客的简单使用
    每日思考(2020/05/06)
    每日思考(2020/05/05)
    每日思考(2020/03/27)
    文件和异常
    每日思考(2020/03/24)
    图形用户界面和游戏开发
    每日思考(2020/03/19)
    面向对象进阶
  • 原文地址:https://www.cnblogs.com/ibelieveyou/p/6773054.html
Copyright © 2011-2022 走看看