runloop学习(一)—— 什么是runloop?

186 阅读3分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

RunLoop

Runloop的概念——本质是一个处理事件的循环

一般来讲,一个线程一次只能执行一个任务,执行完后线程就会退出。

需要一个机制,让线程能随时处理事件但并不退出——event loop

function loop() {
    initialize();
    do {
        var message = get_next_message();
        process_message(message);
    } while (message != quit);

实现Event Loop的关键点在于:如何管理事件/消息,如何让线程在没有处理消息时休眠,以避免资源占用、在有消息来时立刻被唤醒。

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

线程执行了这个函数后,就会一直处于这个函数内部“接受消息—>等待—>处理”的循环中,直到这个循环结束(如传入quit的消息),函数返回。就是有时做事、没事睡觉、有事叫我。

OS/iOS系统中,提供了两个对象:NSRunLoop和CFRunLoopRef。

CFRunLoopRef是在Core Foundation框架内,提供了纯C函数的API,所有这些API,所有这些API都是线程安全的。

NSRunLoop是基于CFRunLoopRef的封装,提供面向对象的API,但是这些API不是线程安全的。

CF Run LoopRef是苹果开源的opensource.apple.com/tarballs/CF…

Runloop与线程的关系—线程与runloop一一对应

iOS开发中能遇到两个线程对象:pthread_t 和 NSthread。

pthread_t和NS Thread是一一对应。可以通过pthread_main_np()来获取主线程;也可以通过pthread_self()来获取当前线程。CFRunLoop是基于pthread来管理的。

我们不能直接创建RunLoop,但可以获取到系统提供的runloop对象,Apple提供两个自动获取的函数:CF RunLoopGetMain()和CFRunLoopgetCurrent()。

主线程的runloop会在应用启动时完成启动,其他线程的runloop需要我们手动启动。

Input Source 和 Timer Source

runloop 事件的来源

input source又可以分为三类:

  • Port-Based sources,系统底层的Port事件,例如CFSocketRef,在应用层基本用不到;
  • Custom Input Source,用户手动创建的Source
  • Cocoa Perform Selector Source, Cocoa提供的perform Selector系列方法,也是一种事件源

TimerSource是定时器事件

Runloop Observer

Runloop 通过监控 Source 来决定有没有任务要做,除此之外,我们还可以用 Runloop Observer 来监控 Runloop 本身的状态。

Runloop Observer 可以监控下面的 runloop 事件:

  • The entrance to the run loop(进入runloop)
  • When the run loop is about to process a timer(处理关于计时器的runloop)
  • When the run loop has woken up, but before it has processed the event that woke it up(在处理runloop相对应的事件前,runloop已经被唤醒)
  • The exit from the tun loop(退出runloop)

Runloop Mode

在监视与被监视中,runloop要处理的事件还挺复杂。为了让runloop能专心处理自己的那部分事情,引入runloop mode 概念。

Runloop Mode实际上是Source,Timer和Observer的集合,不同的Mode吧不同组的Source、Timer 和 Observer 隔绝开来,让其互不影响。Runloop 在某个时刻只能跑在一个 Mode 下,处理这一个 Mode 当中的 Source,Timer 和 Observer。

Apple文档中提到的Mode有五个,分别是:

  • NSDefaultRunLoopMode
  • NSConnectionReplyMode
  • NSModalPanelRunLoopMode
  • NSEventTrackingRunLoopMode
  • NSRunLoopCommonModes

相关资料:hit-alibaba.github.io/interview/i… www.cocoachina.com/articles/11…