Objective-C 【記憶體管理&手動記憶體管理 綜述】

來源:互聯網
上載者:User

標籤:objective-c   記憶體管理   手動記憶體管理   

———————————————————————————————————————————
記憶體管理

(1)Objective-C的記憶體管理



棧區    存放局部變數(由於基礎資料型別 (Elementary Data Type)佔用的儲存空間是固定的,由系統去分配,我們不用去管,故棧區存放基礎資料型別 (Elementary Data Type),)

堆區    存放程式運行過程中動態分配的記憶體空間(物件類型是程式運行過程中動態分配的,他們的大小不固定。比如說是我們Person new申請來的,存放在堆區,也是我們需要管理的)

★所以記憶體管理的範圍是   繼承了NSObject的所有對象(堆區中的對象)
★這是為什麼呢?因為代碼執行完畢後,堆記憶體 不會自動釋放(需要記憶體管理機制),而 棧記憶體 會自動釋放(自動彈棧)

引用計數器     (一般用%ld或者%tu去查看裡面的值,無符號的)

每個對象都有自己的引用計數器,它是一個整數表示對象被引用的次數,即現在有多少東西在使用這個對象,引用計數器的值變為0時,對象就銷毀

①每一個對象剛生下來的時候,引用計數器都是1(對象一旦建立好,預設的引用計數器就是1)

②如果對象的引用計數器不為0,那麼在整個程式的運行過程中,它佔用的記憶體就不可能被回收(除非整個程式退出)

③當使用alloc、new或者copy建立一個對象時,對象的引用計數器預設就是1


(2)Objective-C的記憶體管理分類

Objective-C提供了三種記憶體管理的方式:

①Mannul Reference Counting(MRC,手動管理,在開發 iOS 4.1之前的版本項目時我們要自己負責使用引用計數來管理記憶體,比如手動retain、release、autorelease等。而在iOS之後的版本我們可以使用ARC,讓系統自己管理記憶體)

②Automatic Reference Counting(ARC,自動引用計數,iOS 4.1後推出)

③Garbage Collection(記憶體回收,iOS不支援記憶體回收)

★蘋果官方推薦我們使用ARC技術來管理記憶體,MRC理解就好


———————————————————————————————————————————
手動記憶體管理(MRC)

(1)首先我們要手動記憶體管理(MRC),就要先將自動管理關閉(關閉ARC)。

關閉ARC的方法:

點擊項目(總的,藍色)——> bulid setting ——> basic level ——>搜尋 Objective-C Automatic Reference Counting ——> 此時會出現四個選項,全部設為 No 即可

(2)我們判斷對象是否需要回收,這是就要查看引用計數器的值,需要調用
-(NSInteger)retainCount方法(這是一個有返回值的對象方法,返回值為NSInteger,NSInteger是一個動態類型,他的類型在不同的作業系統可能是int類型,也可能是long類型,他是有符號的。而NSUInerger是無符號類型,沒有負數)

retainCount的返回值  > 0   不會回收
retainCount的返回值  = 0   回收記憶體空間

★注意:這裡retainCount的返回值是 %tu 或者是 %ld 類型的~

(3)回收對象記憶體空間的時候通常會自動調用一個方法,dealloc(釋放對象的屬性)

我們可以通過重寫dealloc這個方法來看看到底對象空間有沒有被釋放(再裡面加一句話輸出,如果釋放了就會自動調用dealloc,那麼這句話就會輸出)

★這裡注意重寫dealloc和重寫init一樣,要先調用父類的dealloc方法,即  [super dealloc]; ,原因不再多說

(4)有兩個對象方法可以使對象的引用計數器的值增加1和減少1

①使用 release  可以使引用計數  -1
②使用 retain     可以使引用計數  +1

(5)記憶體管理

我們應該心裡有這麼一個觀念,就是讓對象的引用計數保持一個平衡的狀態

即:    retain + new = release  (增加引用計數=減少引用計數)


代碼:

#import <Foundation/Foundation.h>

@interface Person : NSObject
-(void)run;
@end

#import "Person.h"

@implementation Person
- (void)dealloc
{
    NSLog(@"對象記憶體空間釋放!");
    [super dealloc];//這句話一定要放在重寫dealloc方法的最後一句,意義是:先釋放子類佔用的記憶體空間,再釋放父類佔用的記憶體空間(和重寫構造方法正好相反,初始化對象時是先執行父類的init,再執行子類的初始化)
//    另外注意,永遠不要直接調用dealloc方法,如果調用應該讓retainCount = 0,但是如果你寫 [p dealloc] 也是不會報錯的,只是沒有必要!這壓根就是一個不需要你自己閑的蛋疼去寫的一句話。
}
-(void)run
{
    NSLog(@"run!");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p=[Person new];
        
        NSLog(@"p->retainCount = %tu",[p retainCount]);
//        這個地方因為建立了p,所以引用p的次數+1,所以輸出的值為1。但是記住,這裡必須將ARC關閉,如果不關閉是會報錯的
        
        [p run];
        NSLog(@"p->retainCount = %tu",[p retainCount]);
//        這裡輸出結果還是1,因為 [p run]; 只是調用了run方法,但是p被引用的次數還是1
        
        [p release];
//        這裡將引用計數-1,所以說此時引用計數為0,也就是此時將會自動調用dealloc方法,列印我們重寫dealloc裡面的“對象空間釋放!”
         
        //        [p run];   //對象空間都釋放了,但還是可以調用的,這是為什麼呢?這個問題留在下節“單個對象的記憶體管理(野指標)去解釋”            
   }
    return 0;
}


———————————————————————————————————————————

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Objective-C 【記憶體管理&手動記憶體管理 綜述】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.