標籤:
參考:http://blog.csdn.net/hahahacff/article/details/39839571
看了視頻、文章後總結一下自己理解的Objective-C的記憶體管理。
本文從上到下時逐步深入的。
ARC
1.手動記憶體管理的基本操作函數及原則(黃金法則或配對原則)
記憶體的開闢和銷毀時成對出現的。
在一個代碼快中出現了alloc,new,retain,copy,mutabcopy等關鍵詞,當對象不再使用後,就要有對應的release,autorelease 出現與之相對應。
當對象的“引用計數”(retainCount)變為“0”時對象執行dealloc函數,執行銷毀操作。
2.當一個類中執行個體化一個對象時我們可以簡單的使用alloc 和 release 解決配對問題。
Person *p = [[Person alloc] init];
[p run];
[p release];
3.當一個類最為另一個類的屬性時(被另一個類持有)應該怎樣配對呢?
對象 alloc;
被持有;-----------------》 被持有就是執行set方法:所以在set方法中應該retain 對象,在dealloc函數中release對象。
對象 release;
ps. 以上時兩對 記憶體操作。
4.當有兩個對象交替被另一個對象持有時改怎樣操作呢?
由於交替操作會使第一個被持有的對象造成記憶體泄露。
所以在第一個被持有的對象在本類中不在使用後立刻release,即在set方法中release 第一個被持有的對象。
代碼:
- (void)setCar:(Car *)car
{
[_car release];
_car = [car retain];
}
5. 當同一個對象多次被另一個對象持有時會造成第一個對象被過早釋放。(殭屍對象,野指標的出現)(野指標的處理方法是給野指標賦值nil,p = nil)
上面的set方法就會出錯。
因此我們需要判斷兩次持有的對象是不是同一個對象。
代碼如下:
- (void)setCar:(Car *)car
{
if(_car != car)
{
[_car release];
_car = [car retain];
}
}
最後的dealloc也需要重寫:
- (void)dealloc
{
[_car release];
[super release];//最後調用,因為父類執行release後會將子類銷毀,下面的代碼就不會執行了,造成記憶體泄露。子類的真正銷毀是在父類中執行的。
//ARC中,可以重寫dealloc函數,但是不能寫[super release];
}
[email protected]的使用
@property 時為簡化get,set方法設計的。我們完全可以用展開的get,set 方法代替。
相關參數:
屬性關鍵字 |
使用範圍 |
釋義 |
是否是預設值 |
小貼士 |
assign |
賦值方式 |
不複製不保留,直接賦值 |
YES |
基礎資料型別 (Elementary Data Type)和本類不直接擁有的對象 |
retain |
賦值方式 |
將新值保留一份賦覆蓋原值 |
NO |
大部分對象可使用 |
copy |
賦值方式 |
將新值複製一份賦覆蓋原值 |
NO |
字串選擇性使用 |
readwrite |
讀寫權限 |
產生getter和setter兩個方法 |
YES |
變數可讀取可修改 |
readonly |
讀寫權限 |
只產生getter方法 |
NO |
變數唯讀不可修改 |
atomic |
原子性 |
原子操作 |
YES |
可以保留在多線程環境下,能安全的存取值 |
nonatomic |
原子性 |
非原子操作 |
NO |
不產生多線程同步內容 |
getter |
存取方法 |
自訂取方法 |
NO |
|
setter |
存取方法 |
自訂賦值方法 |
NO |
|
NSString 需要使用copy
@property(nonatomic,copy) NSString *str;
代理中的寫法:
@property(nonatomic,assign)id<findapartment> delegate; 因為被代理對象並不是真的持有代理對象,所以為了避免對象的循環參考此處必須使用assign!!
@property(nonatomic,weak) __weak id<findapartment> delegate; ARC中寫法。
block中的寫法:
@property(nonatomic,retain)int (^changeColor)(int a,int b); MRC
@property(nonatomic,strong)int (^changeColor)(int a,int b); ARC,好像沒有什麼特殊的%>_<%。。
7.autorelease
autorelease 主要用於類方法的書寫中。
(1)ios 5.0以前的建立方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
`````````````````
[pool release];//[pool drain];用於mac
(2)Ios5.0以後,且ARC中只能使用這種方式!!!!
@autoreleasepool
{//開始代表建立自動釋放池
·······
}//結束代表銷毀自動釋放池
8.循環參考
解決方案:
1. 在標頭檔中用@class 聲明類。在m檔案中引用檔案。
2.兩端循環參考的解決方案
一端使用retain,一端使用assign(使用assign的在dealloc中也不用再release)
ARC:
ARC新增兩個武功高強的左右護法:strong 和 weak
strong的含義和retain相同,weak和assign相同,修飾完的屬性變數用法也是完全沒有改變,不過strong和weak只能修飾對象。
蘋果官方對於ARC機制中對象的記憶體引用規則:
(1)任何對象,如果仍有持有人,就不會銷毀
(2)任何對象,已經沒有任何持有人,即自動銷毀
持有人就是指向對象的指標,如果是strong修飾的,即是對象的持有人,如果是weak屬性的,則不是持有人
彩蛋:讓程式相容ARC和非ARC部分。轉變為非ARC -fno-objc-arc 轉變為ARC的, -f-objc-arc 。
Objective-C記憶體管理