程序启动后,苹果在主线程 RunLoop
里注册了2个 Observer
:
-
第1个 Observer
监听的事件是kCFRunLoopEntry
(即将进入Loop),其回调内会调用_objc_autoreleasePoolPush()
创建自动释放池。其order = -2147483647
,优先级最高,保证创建释放池发生在其他所有回调之前 -
第2个 Observer
监听了两个事件:kCFRunLoopBeforeWaiting
(准备进入休眠) 和kCFRunLoopExit
(即将退出Loop),其order = 2147483647
,优先级最低,保证其释放池子发生在其他所有回调之后。
kCFRunLoopBeforeWaiting
(准备进入休眠)时,会调用_objc_autoreleasePoolPop()
和_objc_autoreleasePoolPush
释放旧的池并创建新池;kCFRunLoopExit
(即将退出Loop)时,会调用_objc_autoreleasePoolPop()
来释放自动释放池。
在程序中断点调试 (lldb) : po [NSRunLoop mainRunLoop]
可以看到 MainRunLoop
的 Common mode Items
中就有这两个 Observer
:
observers = (
"<CFRunLoopObserver 0x60000155c140 [0x7fff8062ce40]>{valid = Yes, activities = 0x1, repeats = Yes, order = -2147483647, callout = _wrapRunLoopWithAutoreleasePoolHandler (0x7fff48bc10bc), context = <CFArray 0x600002a6e4c0 [0x7fff8062ce40]>{type = mutable-small, count = 1, values = (\n\t0 : <0x7fc9b880b048>\n)}}",
"<CFRunLoopObserver 0x6000015580a0 [0x7fff8062ce40]>{valid = Yes, activities = 0x20, repeats = Yes, order = 0, callout = _UIGestureRecognizerUpdateObserver (0x7fff4874f06a), context = <CFRunLoopObserver context 0x600000f59030>}",
"<CFRunLoopObserver 0x60000155c000 [0x7fff8062ce40]>{valid = Yes, activities = 0xa0, repeats = Yes, order = 1999000, callout = _beforeCACommitHandler (0x7fff48bf1fb7), context = <CFRunLoopObserver context 0x7fc9b8605030>}",
"<CFRunLoopObserver 0x600001558640 [0x7fff8062ce40]>{valid = Yes, activities = 0xa0, repeats = Yes, order = 2000000, callout = _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv (0x7fff2b43cfa2), context = <CFRunLoopObserver context 0x0>}",
"<CFRunLoopObserver 0x60000155c0a0 [0x7fff8062ce40]>{valid = Yes, activities = 0xa0, repeats = Yes, order = 2001000, callout = _afterCACommitHandler (0x7fff48bf2020), context = <CFRunLoopObserver context 0x7fc9b8605030>}",
"<CFRunLoopObserver 0x60000155c1e0 [0x7fff8062ce40]>{valid = Yes, activities = 0xa0, repeats = Yes, order = 2147483647, callout = _wrapRunLoopWithAutoreleasePoolHandler (0x7fff48bc10bc), context = <CFArray 0x600002a6e4c0 [0x7fff8062ce40]>{type = mutable-small, count = 1, values = (\n\t0 : <0x7fc9b880b048>\n)}}"
)
根据 Run Loop Observer Activities 枚举值:
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), // 即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理 Timer
kCFRunLoopBeforeSources = (1UL << 2), // 即将处理 Source
kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), // 即将退出 Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU // 包含上面所有状态
};
activities = 0x1
:对应kCFRunLoopEntry
activities = 0xa0
:对应kCFRunLoopBeforeWaiting
|kCFRunLoopExit
通过以上分析可知:系统在每个 RunLoop 迭代循环
中都加入了 自动释放池 Push 和 Pop
,Autorelease对象
会在当前的RunLoop 迭代循环结束时
释放
-
CFRunLoopRef 源码:https://opensource.apple.com/tarballs/CF/
网友评论