理下这几大爷之间的关系吧。在理清他们相互关系之前,需要优先明白各自的内容。
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页的相关信息。
网友评论