黑馬程序員----Objective-C學習筆記之內存管理

------Java培訓、Android培訓、iOS培訓、.Net培訓--------

一、內存管理的基本概念及範圍

1、管理範圍:

1)管理任何繼承NSObject的對象,對其他基本數據類型是無效的。

因爲對象和基本數據類型存儲的區域是不一樣的。對象存儲在需要內存管理的堆區,而基本數據類型存放在棧區。

2)對象類型是程序在運行過程中動態分配的,存儲在堆區。

內存管理主要是【對堆區中的對象】的內存管理


二、內存管理的原理和分類

1、對象的所有權及引用計數

1)【所有權策略】

任何自己創建的對象都歸自己所有,可以使用名字以“alloc”和“new”開頭或名字中包含“copy”的方法創建對象,可以使用retain來獲取一個對象的所有權

 

2)【對象的引用計數】retainCount

每個OC對象都有自己的引用計數器,標示【當前對象】當前有多少個東西在使用這個對象,當該對象被創建時,計數器值爲1

3)【引用計數器作用】

是判斷對象要不要回收的依據。

如果引用計數器爲0,則就要回收該對象。

【例外】對象值爲nil時,引用計數器爲0,但不回收空間,因爲根本就沒分配空間

 

4、【對引用計數器的操作】

給對象發送消息,進行相應的計數器操作

【retain消息】使計數器+1,該方法返回對象本身

【release消息】使計數器-1,並不代表釋放對象

【retainCount消息】獲得對象當前的引用計數器值  %ld  %lu

 

5、【對象的銷燬】

當一個對象的引用計數器爲0時,那麼它將被銷燬,其佔用的內存被系統回收

當對象被銷燬時,系統會自動向對象發送一條【dealloc】消息,一般會重寫dealloc方法,在這裏釋放相關的資源。一旦重寫了dealloc方法就必須調用[super dealloc],並且放在代碼塊的最後調用,不能直接調用dealloc方法。

一旦對象被回收,那麼他所佔據的存儲空間就不再可用,堅持使用會導致程序崩潰

 

【注意】

1)如果對象的計數器不爲0,那麼在整個程序運行過程中,它所佔用的內存就不可能被回收(除非整個程序已經退出)

2)任何一個對象,剛生下來的時候,引用計數器都爲1。當使用alloc、new或者copy創建一個對象時,對象的引用計數器默認就是1.

 

2、OC內存管理的分類

OC中提供了三種內存管理方式:

  1. Mannul Reference Counting MRC手動管理方式
  2. AutomaticReference Counting ARC自動引用計數
  3. Garbagecollection垃圾回收。但是IOS中不支持該技術

 

開發中如何使用:需要理解MRC,但是實際儘量使用ARC


三、手動內存管理入門

【首先關閉ARC】

1、手動管理內存實例

#import <Foundation/Foundation.h>

#pragma mark Person類定義部分
@interface Person : NSObject

@property NSString *name;
@property int age;
@end
#pragma mark Person類實現部分
@implementation Person
//對象的臨終遺言,對象銷燬時,會默認調用該方法
//【注意】該方法是系統根據引用計數器自動調用的,不需要手動調用
-(void)dealloc{
    NSLog(@"This person dead....");
    //再釋放父類
    [super dealloc];
}
@end

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        //用Person類實例化一個對象
        Person *p = [Person new];//此時對象的所有者是自己
        
        //證明該對象有一個所有者
        NSInteger count = [p retainCount];
        NSLog(@"count1 = %lu",count);
        
        //引用計數器+1
        //兩個指針指向一個對象,但是下面這個方法並不能是計數器+1
        Person *p2 = p;
        count = [p2 retainCount];
        NSLog(@"count2 = %lu",count);
        //只有通過retain方法可以使計數器+1
        Person *p3 = [p retain];
        count = [p retainCount];
        NSLog(@"count3 = %lu",count);
        
        //想要回收對象,則要想辦法是retainCount從2變成0
        [p release];
        [p3 release];
        //想要證明person對象被釋放了,可以重寫其dealloc放法
    }
    return 0;
}

打印結果:

2015-10-06 10:32:56.855 MRCDemo[925:303] count1 = 1

2015-10-06 10:32:56.857 MRCDemo[925:303] count2 = 1

2015-10-06 10:32:56.857 MRCDemo[925:303] count3 = 2

2015-10-06 10:32:56.858 MRCDemo[925:303] This persondead....


發佈了65 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章