內(nèi)存管理與引用計數(shù)

引用計數(shù)式內(nèi)存管理的思考方式

引用計數(shù)式的內(nèi)存管理方式主要涉及四個操作:生成對象,持有對象,釋放對象,廢棄對象。

  • 內(nèi)存管理的思考方式

    • 自己生成的對象,自己持有
    • 非自己生成的對象,自己也能持有
    • 不再需要自己持有的對象時釋放
    • 非自己持有的對象無法釋放

與oc中方法對應(yīng)如下:

+對象操作                       +Oc方法
生成并持有對象             alloc/new/copy/mutablecopy等方法
持有對象                        retain方法
釋放對象                        release方法
廢棄對象                        dealloc方法
  • 自己生成的對象,自己持有

使用alloc, new, copy, mutablecopy開頭的方法意味著自己生成的對象自己持有

注:命名要符合駝峰命名法。

  • 非自己生成的對象,自己也能持有

通過retain方法,非自己生成的對象也可以持有對象了。

  • 不再需要自己持有的對象時釋放

自己持有的對象,一旦不再需要,持有者有義務(wù)釋放該對象。釋放使用release方法。

使用autorelease方法可以使取得的對象存在,但是自己不持有對象。

  • 無法釋放非自己持有的對象

釋放非自己持有的對象會造成程序的崩潰。

GNUSTEP和APPLE中alloc/retain/release/dealloc的實現(xiàn)

在申請內(nèi)存的時候,會在內(nèi)存頭部之前申請一塊內(nèi)存用來保存引用計數(shù)。然后分別在不同的操作的時候?qū)@一引用計數(shù)值進行判斷并作相應(yīng)調(diào)整。總結(jié)如下:

1.調(diào)用alloc或是retain方法后,引用計數(shù)值加1。
2.調(diào)用release之后,引用計數(shù)值減1
3.引用計數(shù)值為0時,調(diào)用delloc方法廢棄對象

蘋果在實現(xiàn)上述方式時沒有使用內(nèi)存頭部管理引用計數(shù),而是使用采用了散列表管理引用計數(shù)

autorelease

自動釋放--autorelease

aurorelease就是自動釋放,類似于c語言中的自動變量。

autorelease的具體使用方法:

1,生成并持有NSAutoreleasePool對象
2,調(diào)用已分配對象的autorelease實例方法
3,廢棄NSAutoreleasePool對象

在Cocoa框架中,相當于程序主循環(huán)的NSRunloop或者在其他程序可運行的地方,對NSAutoreleasePool對象進行生成,持有和廢棄處理。

ARC規(guī)則

所有權(quán)修飾符:

  • _strong修飾符
  • _weak修飾符
  • _unsafe_unretained修飾符
  • _autoreleasing修飾符

_strong修飾符

_strong修飾符是id類型和對象類型默認的所有權(quán)修飾符。附有_strong修飾符的變量在超出其變量作用域時,釋放其被賦予的對象。_strong修飾符表示對對象的“強引用”,持有強引用的變量在超出其作用域時被放棄,隨著強引用的失效,引用的對象會隨之釋放。通過_strong修飾符,不必再次鍵入retain或者release,就完美的滿足了“引用計數(shù)式內(nèi)存管理的思考方式”。

注:id類型和對象類型的所有權(quán)修飾符默認為_strong修飾符。

_weak修飾符

如果僅使用_strong修飾符會造成“循環(huán)引用”的問題,這個時候就用到了_weak。帶有_weak修飾符的變量不持有對象,所以在超出其變量作用域時,對象即被釋放。_weak的另一個優(yōu)點是,在持有某對象的弱引用時,若該對象被釋放,則此弱引用將自動失效且處于nil被賦值狀態(tài)。

_unsafe_unretained修飾符

在ios5以下版本中無法使用_weak,所以_unsafe_unretained成為替代品。但是_unsafe_unretained不保證最后的對象被釋放,且處于nil被賦值狀態(tài)。所以賦值給附有_unsafe_unretained修飾符變量的對象在使用時,要確保它存在。

_autoreleasing修飾符

在ARC有效時,用“@autoreleasepool塊”來代替“NSAutoreleasePool”。

編譯器會檢查方法名是否以alloc/new/copy/mutableCopy開始,如果不是則自動將返回值的對象注冊到autoreleasepool(注:init返回值的對象不注冊到autoreleasepool)。在使用附有_weak修飾符的變量時必須訪問注冊到autoreleasepool的對象,因為_weak修飾符持有對象的弱引用,在訪問引用對象的過程中,該對象可能被丟棄,所以把要訪問的對象注冊到autoreleasepool中,那么在@autoreleasepool結(jié)束之前多能確保該對象存在。

屬性

      屬性聲明的屬性                       所有權(quán)修飾符
        assign                          _unsafe_unretained
        copy                            _strong
        retain                          _strong
        strong                          _strong
        unsafe_unretained               _unsafe_unretained
        weak                            _weak

其中:
assign:一般基本變量用該屬性聲明,eg:int BOOL

copy:聲明的變量是拷貝賦值源所生成的對象

retain和strong表示意思相同

strong:屬性所聲明的變量將成為對象的持有者

unsafe_unretained:ios5之前的系統(tǒng)用該屬性代替weak

關(guān)于ARC認識很好的博文,一個系列,值得一讀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容