RunLoop笔记
原文:Runloop基础元素解析 http://www.jianshu.com/p/8b9c81a521bc?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-timeline&from=timeline&isappinstalled=0
Runloop笔记
作用:保持程序运行,处理各类事件,节省CPU资源提高程序性能、没有事件时就进入休眠状态。
一个Thread对应一个一个runloop,runloop为惰性加载(除了主线程对应的runloop)。
Mode:
一个Runloop可以包涵多个Mode,但是每次RunLoop启动只能指定其中一个Mode。Mode有5中类型分别是CFDefaultRunLoopMode(主线程的默认Mode)、UITrackingRunloopMode(界面跟踪的Mode用于ScrollView追踪触摸滑动)、CFCommonRunLoopMode(占位Mode,并不是真正的Mode)之间可以相互切换。如果想切换只能退出当前Loop再重新定制一个Mode进入。
事件源:(Source\Timer\Observer)
CFRunLoopTimeRef:
基于时间的触发器,一般指NSTimer,包含一个回调函数指针和一个时间长度。
由于NSTimer在RunLoop中处理,受其影响较大,所以有时不准确(可换GCD定时器不受RunLoop影响)。
(1)[NSTimer scheduledTimerWithTimeInterval:]创建一个timer并自动把它制定到一个默认的runloop中去。且只在CFDefaultRunLoopMode模式下能正常运行。
可使用[[NSRunloop mainRunLoop]addTimer:forMode:CFCommonRunLoopMode];对其Mode进行修改。
(2)[NSTimer timerWithTimeInterval:]创建一个timer,这时需要我们手动把它添加到一个runloop中去。
CFRunLoopSourceRef:
分类:
(1)source0:基于port的,Port-Based Source
(2)source1:不基于port的,Custom Input Sources和Cocoa Perform Selector Sources
CFRunLoopObserverRef:
观察者,监听RunLoop状态的变化:
进入、退出RunLoop、即将唤醒、即将进入睡眠、即将处理timer、即将处理Source、所有活动。
RunLoop与自动释放池的关系:
如果看runloop的机制,其实会知道,一个运行循环对应一个线程,而且每个运行循环都会有单独的一个自动释放池,其实自动释放池是寄生于runloop的
在每一个事件周期(event cycle)的开始,系统会自动创建一个自动释放池;在每一个事件周期的结尾,系统会自动销毁这个自动释放池。一般情况下,你可以理解为:当你的代码在持续运行时,自动释放池是不会被销毁的,这段时间内你也可以安全地使用自动释放的对象;当你的代码运行告一段落,开始等待用户输入(或者其它事件)时,自动释放池就会被释放掉,池中的对象都会收到一个release消息,有的可能会因此被销毁。
注意:autoreleasepool是没有单独的内存结构的是通过以autoreleasePoolPage为结点的双向链表实现。每个thread中都会维持一个stack, 其中放置着所有在这个thread中创建但未销毁的pool, 每当一个新的pool创建后, 它就位于stack的最顶端, 相应autoreleased object就会放入其中. 当pool drain的时候, 它就会从stack的顶端移除, 并且release掉其包含的objects.