自动释放池 + 线程 + RunLoop 关系

理下这几大爷之间的关系吧。在理清他们相互关系之前,需要优先明白各自的内容。

runLoop:

下面为runloop的经典视图。


image.png

image.png
  • runLoop 实际上是一个do while 的底层循环机制。

  • Source0 指的是UI触发事件、页面刷新事件、timer等自定义事件。Source1 指的是系统自己的核心事件。

  • 线程和runloop 之间为一一对应的关系,以线程为key,runloop为value,建立联系。当主线程创建的时候,默认创建一个runloop对象,一般处于休眠等待唤醒的状态。 当有事件:页面刷新、NSTimer、UI点击等时,会唤醒RunLoop。Runloop会do while处理唤醒时收到的消息,激活timer计时,处理Source0,处理Source1,结束后进入休眠状态。

  • runloop有两个很重要的状态:
    **
    kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
    kCFRunLoopAfterWaiting = (1UL << 6), //刚从休眠中唤醒
    **
    每当进入上面两个状态的时候,都会意味着 销毁旧的自动释放池,创建新的自动释放池。

  • 每一个线程对应着一个 runloop。每个runloop 对应着多个 modeItems。 每个ModeItem 对应着 多个事件。 所以当Runloop被唤醒的时候,意味着do modeItems 的执行。

自动释放池:

  • 本质: 它内部是一个存放指针的栈结构,是一个双向链表对象。内部为页的结构,由Boundary 哨兵对象防止越界。每页的大小为 4060个字节。如果超过则开启新的一页。在app 初始化的时候第一次创建,app销毁的时候最后一次销毁。
  • 自动释放池的函数有两个方法,一个pop,一个push。
  • 压栈过程:
    1. 判断当前是否有页的存在,如果没有则开启新的一页,并设置boundary,将当前页设置为 hotpage。
    2. 如果当前页存在且没有满,直接压栈。
    3. 如果满了,寻找子节点(双向链表),创建新的一页,并把新页设置为HotPage。
  • 出栈: 先把当前所有页的对象出栈, 再kill页的相关信息。

你可能感兴趣的:(自动释放池 + 线程 + RunLoop 关系)