一. OC的內存管理的過程xcode
OC爲每一個對象提供一個內部計數器,這個計數器跟蹤對象的引用計數,當對象被建立或拷貝時,引用計數爲1,每次保持對象時,調用retain接口,引用計數加1,若是不須要這個對象時調用release,引用計數減1,當對像的引用計數爲0時,系統就會釋放掉這塊內存,釋放對象調用dealloc。ide
for example:
函數
1.對象在完成建立的同時,內部會自動建立一個引用計數器,這個計數器,是系統用來判斷是否回收對象的惟一依據,當咱們的引用計數retainCount = 0的時候,系統會堅決果斷回收當前對象測試
2.[對象 release] reatinCount - 1編碼
3.[對象 retain] reatinCount + 1 ,返回selfatom
4.咱們的引用計數retainCount = 0的 對象就被銷燬了spa
5.dealloc函數,當一個對象要被銷燬的時候,系統會自動調用dealloc函數,通知對象你將要被銷燬
指針
內存管理原則(配對原則):只要出現了 new,alloc,retain,就必定配對出現一個release,autorelease
code
二.單個對象的內存管理orm
//定義了一個 Person類 //Person.h @interface Person : NSObject @property int age; - (void)run; @end //Person.m - (void)dealloc { [super dealloc]; NSLog(@"Person 被銷燬了"); } //重寫description方法 - (NSString *)description { return [NSString stringWithFormat:@"age = %d",_age]; } - (void)run { NSLog(@"人跑起來了"); }
因而在在主函數中開始了實驗
測試1:
void test1() { //retainCount = 1 Person * p = [[Person alloc] init]; //retainCount = 0 //系統已經將p所指向的對象回收了 //EXC_BAD_ACCESS 訪問了不可訪問的內存空間 //被系統回收的對象咱們稱之爲殭屍對象 //默認狀況下xcode爲了提升編碼效率,不會時時檢查殭屍對象 [p release]; //不能調用run方法 [p run]; }
結論:系統將對象回收後,對象變成殭屍對象,不能再調用對象方法
解決辦法:若是你肯定當前做用於中的對象已經不會再被使用了,爲了防止野指針操做,一般咱們會把不在使用的指針變量賦值爲nil p = nil;
測試2
void test2() { //內存泄漏第一種狀況 //1 Person * p = [[Person alloc] init]; p.age = 20; NSLog(@"%@",p); //2 [p retain]; //3 [p retain]; //2 [p release]; //只要對象的retainCount != 0 就會一直存在在內存中 //內存泄漏指的就是,再也不被使用的對象,一直在內存中沒有被銷燬 //內存泄漏第二種狀況 //retainCount = 1 Person * p = [[Person alloc] init]; p.age = 20; [p run]; p = nil; [p release];//[nil release]; */
結論:在上面的實驗中列出了兩種內存泄漏的可能,1.retainCount 不等於0 2.空指針release
測試3:
void test4() { //1 Person * p = [[Person alloc] init]; p.age = 20; NSLog(@"%@",p); //0 [p release]; [p retain]; }
結論:
野指針操做,當一個對象retainCount已經爲0 時,調用retain方法,是不會使得對象起死回生的,同時還會發生野指針操做異常
三.多個對象的內存管理
剛剛只有一我的對象,如今添加一個Car對象,讓Person類包含Car類
@interface Person : NSObject { Car * _car; } - (void)setCar:(Car *)car; - (Car *)car; - (void)drive; @end
爲了防止內存泄漏,Person類銷燬時,Car也銷燬,因而重寫了Person類的
- (void)dealloc { //目的是要保證在p對象存在的時候,car對象必定存在 //對象p被銷燬的時候, [_car release] [super dealloc]; NSLog(@"Person 被銷燬了"); }
四.手動內存管理時出現類之間相互引用的問題
@property(nonatomic,retain) Car * car; @property (nonatomic,assign)Person * person;
當出現兩個類相互引用時,必定要有一個類使用
retain