RunLoop

作者: 小圆菜陪你财务自由 | 来源:发表于2018-10-09 18:30 被阅读0次

在多线程开发中其实简单介绍过了,这里单独拿出来再啰嗦一下。

RunLoop是什么以及它的作用?

首先上一段官网解释:
Run loops are part of the fundamental infrastructure associated with threads. A run loop is an event processing loop that you use to schedule work and coordinate the receipt of incoming events. The purpose of a run loop is to keep your thread busy when there is work to do and put your thread to sleep when there is none.
由这一段我们基本知道它是什么,作用是什么。小编用不好的英文水平大概说 一下:

  1. RunLoop 是 threaed(线程)基本组成的一部分。
  2. 它的作用是保证你的线程在没有事件时也保持sleep(睡眠)状态,有事件时保持busy(唤醒)状态。
  3. 比如触摸、定时器、performSelector等就用到了RunLoop.
RunLoop分类
分类
  1. NSRunLoop---------oc实现
  2. CFRunLoopRef----c实现
分类的关系

NSRunLoop 是基于 CFRunLoopRef 的OC封闭

RunLoop和线程
  1. 线程与RunLoop是一一对应的
  2. 线程创建的时候,并没有创建RunLoop对象,而是在获取的时候自动创建的,但并没有run起来。例如:
    [NSThread detachNewThreadWithBlock:^{
    [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
    NSLog(@"hello");
    }];
    }];
    此时的timer并不会执行,虽然此时已经有了RunLoop对象。
    那要如果执行timer呢?
    添加一句代码:[[NSRunLoop currentRunLoop]run];
  3. 我们的主线程默认是开启了子线程的,这就是我们的app为什么可以一直运行的原因。
RunLoop相关的类(严谨来说是结构体)
  • CFRunLoopRef
  • CFRunLoopTimerRef
  • CFRunLoopSourceRef //可以自定义,但只能定义source0
  • CFRunLoopObserverRef
  • CFRunLoopModeRef
CFRunLoopObserverRef的状态
 kCFRunLoopEntry = (1UL << 0),
     kCFRunLoopBeforeTimers = (1UL << 1),
     kCFRunLoopBeforeSources = (1UL << 2),
     kCFRunLoopBeforeWaiting = (1UL << 5),
     kCFRunLoopAfterWaiting = (1UL << 6),
     kCFRunLoopExit = (1UL << 7),
     kCFRunLoopAllActivities = 0x0FFFFFFFU
RunLoop实现休眠的原理, 真正的原因是
  1. 调用了内核的API(mach_msg), 进入内核态,由内核来将线程置于休眠
  2. 有消息,就唤醒线程,回到用户态,来处理消息.
运行方式
  1. 一个RunLoop对应着一条线程
  2. 一个RunLoop包含多个Mode,每个 Mode 又包含若干个 Source/Timer/Observer
  3. Source/Timer/Observer又叫mode item。不同mode下的mode item互不影响
  4. RunLoop运行过程中,只选择一种模式运行
  5. 切换Mode,程序退出当前RunLoop mode,再重新指定Mode执行
总结
  1. RunLoop有什么用?
  • 保持程序的持续运行
  • 处理App中的各种事件(触摸、定时器、PerformSelector)
  • 节省CPU资源、提高程序性能:
    该做事的时候做事,该休息的时候休息。
补充:
NSTimer不准时的原因:
1. 受RunLoop循环时间的影响
2. 受RunLoop mode的影响

#gcd timer与NSTimer是不同的:
都是源,一个是RunLoop的源,一个Dispatch的源
GCD timer不需要加入mode

#GCDTimer总结:
GCDTimer精度高
GCDTimer主线程执行会RunLoop影响,子线程不受影响
GCDTimer不受模式切换的影响

GCD timer要更准时一些,详细使用不介绍了,比较复杂。

相关文章

网友评论

      本文标题:RunLoop

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