iOS進階四-自動釋放池原理


概述

AutoreleasePool(自動釋放池)是OC中的一種內存自動回收機制,它可以延遲加入AutoreleasePool中的變量release的時機。在正常情況下,創建的變量會在超出其作用域的時候release,但是如果將變量加入AutoreleasePool,那么release將延遲執行。

@autoreleasepool實現本質

在終端中使用clang -rewrite-objc命令將OC代碼重寫成C++的實現

 

 __AtAutoreleasePool是C++定義類

 

 @autoreleasepool最終實現如下

 AutoreleasePoolPage

自動釋放池的主要底層數據結構是:__AtAutoreleasePool 和 AutoreleasePoolPage

調用了autorelease的對象最終由AutoreleasePoolPage對象來管理

 objc4源碼:NSObject.mm

 

每一個AutoreleasePoolPage對象占用4094字節內存,本身成員占用56字節,剩下的空間用來存放autorelease對象的地址

所有的AutoreleasePoolPage對象通過雙向鏈表的形式連接在一起

 

AutoreleasePoolPage管理autorelease的的對象過程 

@autoreleasepool {}就對應 objc_autoreleasePoolPush(); 和  objc_autoreleasePoolPop(atautoreleasepoolobj);

objc_autoreleasePoolPush(); 內部實現:往當前hot AutoreleasePoolPage 添加 POOL_BOUNDARY,返回POOL_BOUNDARY所在的內存地址

@autoreleasepool {}代碼快如果存在對象調用了autorelease,就會將對象內存地址保存至AutoreleasePoolPage 

objc4 NSObject.mm 對象- (id)autorelease方法實現

 

添加POOL_BOUNDARY和AutoreleasePoolPage對象后如下圖 

每執行@autoreleasepool底層對應執行objc_autoreleasePoolPush(); 就會往AutoreleasePoolPage添加POOL_BOUNDARY,並返回POOL_BOUNDARY所在AutoreleasePoolPage的內存空間地址

@autoreleasepool{}大括號結束 內部創建的__AtAutoreleasePool對象銷毀,調用析構函數objc_autoreleasePoolPop(atautoreleasepoolobj);

AutoreleasePoolPage開始從后往前遍歷autorelease對象調用release方法直到objc_autoreleasePoolPop()傳入的POOL_BOUNDARY地址為止

 查看AutoreleasePoolPage結構

Foundation內部存在一個全局的函數 聲明引用 然后在調用

控制台輸出

 

 RunLoop與autorelease

iOS程序運行 在主線程中注冊了2個Observer 分別監聽RunLoop的 kCFRunLoopEntry  kCFRunLoopBeforeWaiting 兩個狀態(通過打印主線程的RunLoop)

第一個Observer監聽了kCFRunLoopEntry 會調用objc_autoreleasePoolPush

第二個Observer監聽了kCFRunLoopBeforeWaiting 會調用objc_autoreleasePoolPop

 MRC環境 調用的autorelease對象銷毀時機

iOS程序在程序入口main函數執行@autoreleasepool也就是atautoreleasepoolobj = objc_autoreleasePoolPush();操作  保證在程序中對象可以直接調用autorelease 

上圖中person對象是有RunLoop來控制的,它可能是在某次RunLoop循環中,RunLoop休眠之前調用了release 

ARC環境 方法中創建局部對象銷毀時機 

上圖中person對象取決於ARC是對person添加釋放代碼是生成autorelease還是在方法結束之前生成release,經過調試驗證ARC在方法結束前插入一句

[person release],所以ARC下局部對象是在方法結束釋放

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM