美文网首页
RunLoop-基础概念(初识篇)

RunLoop-基础概念(初识篇)

作者: Zombie_Coder | 来源:发表于2018-01-27 17:37 被阅读5次

学习这篇内容主要讲解RunLoop的概念,以及RunLoop和线程之间的关系。
当然提及RunLoop也离不开Autorealse Pool,本篇内容略有提及,但不重点阐述。
本篇内容是我自己对RunLoop概念的总结,和简单呈现,内容比较精炼。

概念
  • RunLoop是系统中和线程相关的基础架构的组成部分,一个RunLoop是一个事件处理环,系统利用这个事件处理环来安排事务。
  • RunLoop的意义是让你的线程在有工作的时候去干活,没有工作的时候进入休眠节省系统资源。
  • 每个线程(包含主线程)都有一个Runloop。对于每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的Autorelease Pool会构成一个像callstack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个Pool里的每个Object会被release。
  • RunLoop和线程之间是以键值对应的形式一一对应的,其中key是thread,value是RunLoop,RunLoop也是管理线程的一种机制,这种机制不仅在iOS上有,在安卓的Looper,Node.js中的EventLoop都有类似的模式。
    唤醒一个线程其实就是唤醒线程的source。

一、初识RunLoop

首先,我们在主线程中添加如下代码:

while (1) {
    NSLog(@"while begin");
    // the thread be blocked here
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    // this will not be executed
    NSLog(@"while end");
}

我们将上面代码在主线程运行,我们会发现while end没有执行,过一会又执行了,这是因为:

  • 主线程中,本身有自己的RunLoop,所以主线程可以一直不被释放,在需要做事情的时候主线程被唤醒干活,
  • 在不需要做事情的时候主线程会休眠,所以上面代码到distantFuture休眠线程后,会停止执行,当主线程需要处理某些事情的时候才会被唤醒。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    while (1) {
        NSLog(@"while begin");
        NSRunLoop *subRunLoop = [NSRunLoop currentRunLoop];
        [subRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        NSLog(@"while end");
    }
});

上面的代码是通过GCD开启全局的一个子线程,运行代码后,在子线程会无限循环的一直在跑,不会停!这是因为:

  • 这个RunLoopModlesources为空、observers为空、timers为空,所以这个RunLoop直接就结束释放了.
  • 我们看到虽然有Mode,但是我们没有给它soures,observer,timer,其实Mode中的这些source,observer,timer,统称为这个Mode的item,如果一个Mode中一个item都没有,则这个RunLoop会直接退出,不进入循环(其实线程之所以可以一直存在就是由于RunLoop将其带入了这个循环中)。下面我们为这个RunLoop添加个source:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    while (1) {
        NSPort *macPort = [NSPort port];
        NSLog(@"while begin");
        NSRunLoop *subRunLoop = [NSRunLoop currentRunLoop];
        [subRunLoop addPort:macPort forMode:NSDefaultRunLoopMode];
        [subRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        NSLog(@"while end");
        NSLog(@"%@",subRunLoop);
        
    }
});

上面的代码,运行后,会停在休眠的那一行代码,因为我们给RunLoop的model添加item.

小结:我们的RunLoop要想工作,必须要让它存在一个Item(source,observer或者timer),主线程之所以能够一直存在,并且随时准备被唤醒就是应为系统为其添加了很多Item.

相关文章

  • RunLoop-基础概念(初识篇)

    学习这篇内容主要讲解RunLoop的概念,以及RunLoop和线程之间的关系。当然提及RunLoop也离不开Aut...

  • RunLoop-基础篇

    前言 2016年6月7号开始编写CFRunLoop,并通过实现代码 NSRunLoop 苹果提供NSRunLoop...

  • Android 基础概念初识

    一、Gradle初识 Gradle 是 Android Studio 的内置版本选项。因此 Android 中具有...

  • runloop-整理中

    runloop-整理中

  • iOS开发GCD

    有关任务和队列的概念在此就不多说了,我的简书有详细记载,上一篇是基础,这一篇是针对-----GCD。 一、初识GC...

  • 初识Rxjs的基础概念

    1.Observable:可观察对象—一个值或事件的流集合;(1) 创建:Rx.Observable.create...

  • 初识Fish Redux在Flutter中使用

    初识Fish Redux在Flutter中使用 本教程需要你在官方教程的基础上有概念性的了解,若你对基础概念不了解...

  • 每次吃一点AndroidのNDK&JNI

    1. 初识NDK&JNI 1.1. 基础概念 JNI(Java Native Interface):java本地接...

  • 2020.11.08 - 2020.12.31 总结

    技术认知篇 Runloop-实际开发你想用的应用场景[https://mp.weixin.qq.com/s/aa-...

  • RunLoop-基础与应用

    RunLoop的概念 一种可以控制线程存在时间,有事的时候干活,没事的时候休息的机制。 OSX/iOS 系统中,提...

网友评论

      本文标题:RunLoop-基础概念(初识篇)

      本文链接:https://www.haomeiwen.com/subject/ppgnaxtx.html