引用計數(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認識很好的博文,一個系列,值得一讀。