iOS開發:淺談內存管理

內存分佈

  • 堆:通常由程序員分配釋放,若程序員不釋放,則可能會引發內存泄漏。其相似於鏈表。
  • 棧:由編譯器自動分配釋放,存放函數的參數值,局部變量等值。其操做方式相似於數據結構中的棧。

內存管理原理

OC語言使用引用計數來管理內存,每一個對象都有一個能夠遞增和遞減的計數器。若是有其餘對象持用該對象的話,那該對象就遞增其引用計數;用完之後就遞減其計數,當引用計數爲0時,就銷燬該對象。程序員

MRC與ARC

Xcode4.2默認設定爲對全部的文件ARC有效。ARC有效指的是編譯器會在編譯時,自動在代碼中加上retain、release等語句管理內存。本質上與MRC是同一套內存管理邏輯,只是開啓ARC後,由編譯器幫咱們管理內存而已。編程

全部權修飾符

ARC有效時,id類型和任何對象類型(對象類型就是指向NSObject這樣的Objective-C類的指針)都必須附加全部權修飾符,全部權修飾符一共有四種:安全

  • __strong修飾符;
  • __weak修飾符;
  • __unsafe_unretained修飾符;
  • __autoreleasing修飾符;
__strong修飾符:
默認狀況下,使用的是__strong修飾符。
它表示的是對對象的「強引用」。持有強引用的變量在超出其做用域時被廢棄,隨着強引用的失效,引用的對象會隨之釋放。
__weak修飾符:
只使用_strong修飾符,有可能產生「循環引用」的問題。__weak修飾符與__strong修飾符相反,提供弱引用。弱引用不能持有對象實例。
__unsafe_unretained修飾符
__unsafe_unretained修飾符與__weak修飾符同樣不持有對象實例。可是賦值給附有__unsafe_unretained修飾符變量時,若是其值不存在時,程序會當即崩潰。
__autoreleasing修飾符
__autoreleasing修飾符等價於在ARC無效時調用對象的autorelease方法。

屬性聲明與全部權修飾符的對應關係

屬性聲明的屬性 全部權修飾符
assign __unsafe_unretained修飾符
copy __strong修飾符(可是賦值的是被複制的對象)
retain __strong修飾符
strong __strong修飾符
unsafe_unretained __unsafe_unretained修飾符
weak __weak修飾符

weak與strong的區別

strong相似於retain,會將對象的引用計數器+1,分配內存地址。
weak相似於指針,只是單純的指向某個地址,可是自己並未分配內存地址。當指向的地址被銷燬時,該指針會自動nil。數據結構

weak與assign的區別

一、修飾變量類型的區別
  • weak 只能夠修飾對象。若是修飾基本數據類型,編譯器會報錯。
  • assign 可修飾對象,和基本數據類型。當須要修飾對象類型時,MRC時代使用unsafe_unretained。固然,unsafe_unretained也可能產生野指針,因此它名字是"unsafe_」。多線程

    二、是否產生野指針的區別
  • weak 不會產生野指針問題。由於weak修飾的對象釋放後(引用計數器值爲0),指針會自動被置nil,以後再向該對象發消息也不會崩潰。 weak是安全的。
  • assign 若是修飾對象,會產生野指針問題;若是修飾基本數據類型則是安全的。修飾的對象釋放後,指針不會自動被置空,此時向對象發消息會崩潰。函數

strong與copy

  • strong對應的setter方法,是將_property先release([_property release]),而後將參數retain([property retain]),最後_property = property.
  • copy對應的setter方法,是將_property先release([_property release]),而後將參數內容copy([property copy]),建立一塊新的內存地址,最後_property = property.

weak的實現

weak的實現是基於哈希表,對象中的屬性被weak修飾時,會以對象的地址爲key,屬性的地址爲value,存儲到哈希表中。當對象被銷燬時,運行時會經過哈希表找到全部用weak修飾的屬性,將其指針自動置爲nil。學習

淺拷貝與深拷貝

概念:
  1. 淺拷貝
    淺拷貝就是對內存地址的複製,讓目標對象指針和源對象指向同一片內存空間,當內存銷燬的時候,指向這片內存的幾個指針須要從新定義纔可使用,要否則會成爲野指針。線程

  2. 深拷貝
    深拷貝是指拷貝對象的具體內容,而內存地址是自主分配的,拷貝結束以後,兩個對象雖然存的值是相同的,可是內存地址不同,兩個對象也互不影響,互不干涉。指針

總結:

這裏貼一個網友的總結
葵花寶典.pngcode

Tip:

因爲文中不少知識均來自於書籍
Objective-C高級編程 iOS與OS X多線程和內存管理
因此這篇文章只能算是一篇學習筆記,由於本人能力有限,若有錯誤,請直接留言指出。

實在是能力有限寫不出比較有價值的東西,只好把網友寫好的文章學習總結了一下,而後直接貼出來。原本都很差意思發表出來,但礙於本身誇下了海口說最近6個月每週一篇文章,因此這篇文章就勉強發了出來。後面仍是要繼續努力,不只要堅持寫博客,還要寫出一些有意義有價值的東西來。

相關文章
相關標籤/搜索