談談 iOS 記憶體管理機制

2021-07-10 06:16:40 字數 1709 閱讀 1851

從最簡單的 c 語言開始說起, c 語言中申請(malloc)到了一塊記憶體, 你可以把這塊記憶體想象成乙個小球, 你有根線牽著它, 這根線就是指標, 並且規定只有通過線才能拿到小球, 乙個小球可以被很多人用線牽著.

c 語言中釋放記憶體, 就相當於把小球直接銷毀, 但可能還有其他人用線牽著這個小球啊, 當你釋放之後, 別人用這個線就找不到這個小球了, 所以別人的線就成為了"野指標", 就不安全了

然後到了 oc 中的管理記憶體, 同樣把記憶體比作小球, 你申請一塊記憶體的時候還是由一根線牽著小球, 但是釋放的時候, 就不讓你直接銷毀那個小球, oc 會給每個小球做個數量標記, 這個標記記錄著有幾根線牽著它! 當有n根線牽著它的時候, 這個標記為 n, 你要釋放記憶體的時候, oc 會把標記的數量減1, 記得 oc 並不會像 c 語言一樣立刻釋放記憶體, 它只是把標記的數量減1而已, 直到標記的數量減為0了, oc 才會去釋放掉那塊記憶體.

知道了原理, 再來看看 oc 的 mrc 記憶體管理機制

如果兩個物件直接複製 obj1 = obj2, 此時 obj1 和 obj2 指向同一塊記憶體, 那塊記憶體的計數為 1, 有兩個指標指著那記憶體, 按道理說應該要是 2 才對啊, 如果要使得那塊記憶體計數為 2, 應該這樣寫

obj1 = [obj2 retain];  要加 retain 關鍵字, 讓記憶體計數器+1, 這樣那塊記憶體的計數才是 2, 此時兩個指標指著同一塊記憶體!, 修改了 obj1 的內容, obj2 也會被修改

釋放的時候 [obj2 release];   release 關鍵字, 讓記憶體計數器-1, 不一定會釋放那塊記憶體, 記得只有減為 0 了才會被釋放, 此時 還有 obj1 指著那塊記憶體吧, 所以記憶體並沒有釋放, 

如果我想修改 obj1 不影響 obj2 的話, 應該使用 copy 關鍵字, 像這樣

obj1 = [obj2 copy];   此時 obj1 和 obj2 指著兩塊不同的記憶體, 每塊記憶體的技術都是 1, 那麼修改 obj1 內容就不會影響到 obj2 的內容了

還有最重要的就是用完了記憶體要記得 release 釋放掉, 不然記憶體會一直占用著, 浪費空間, 有個原則, 誰建立的誰釋放, 不要你建立的, 我來釋放, 這樣程式複雜了會亂的, 造成記憶體洩露.

當程式**變多了, 每次寫 alloc, release, 很累人, 而且很可能忘記寫! 造成記憶體洩露, 為了解決這個, oc 推出了 arc 記憶體管理機制, 叫做自動引用計數, 不用再寫 release 這樣容易忘記寫的語句了, oc 會在編譯期間, 在合適的地方, 自動給你插入這樣的釋放語句, 使程式設計師輕鬆了很多.

arc 中多了幾個關鍵字

weak, weak 不會使得物件的計數器+1, 也就是說, 乙個 weak 的指標, 留不住乙個物件

strong, strong 才會使得物件計數器+1, 當乙個物件有 strong 的指標指著時, 它不會被釋放, 當沒有 strong 指標指著時才會被釋放掉, 並且把那些指向它的 weak 指標全部置為 nil, 避免了野指標的出現.

arc 的引進減輕了程式設計師負擔, 但是又導致了更難排查的"記憶體迴圈引用"問題

我說說原理, 

當乙個物件有 strong 指標指著的時候, 就不會被釋放, 那如果 有兩個物件互相指著對方, 

就像 a->b, b->a, 兩個物件指標形成了乙個環, 這種情況就誰都無法釋放了, 如果有 n 個物件之間形成了環, 那麼就更難查了, 還記得圖論當中的拓撲排序嗎,  拓撲排序可以用來檢測圖中的環, 理論上編譯器可以在編譯期就告訴我們是否發生了記憶體迴圈引用.

iOS 記憶體管理機制

學習要點 1.reference counting 引用計數機制 2.了解mrc apc和gc 3.autoreleasepool 執行機制 4.如何避免 retain cycle reference counting 引用計數機制 cocoa 上基本的記憶體管理機制就是引用計數,通過乙個 refe...

iOS 記憶體管理機制

alloc 與 init 理解 myclass myobj myclass alloc init myclass myobj myclass alloc myobj myobj init alloc 分配了記憶體給物件,讓他不釋放,並且把位址返回給指標。但是這塊記憶體不能使用,因為沒有被正確的 初始...

iOS記憶體管理機制

todo cf和oc之間的轉換 core foundation框架和cocoa foundation框架區別 core foundation框架和foundation框架緊密相關,它們為相同功能提供介面,但foundation框架提供objective c介面。如果您將foundation物件和co...