黑馬程序員-1.內存管理

一. 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
相關文章
相關標籤/搜索