Objective-C:07_記憶體管理

來源:互聯網
上載者:User

標籤:style   color   io   os   使用   ar   strong   for   檔案   

基本原理:

    1、什麼是記憶體管理        -》行動裝置的記憶體極其有限,每個app所能佔用的記憶體是有限制的        -》當app所佔用的記憶體比較多時,系統會發出記憶體警告,這時得回收一些不需要在使用的記憶體空間,比如回收一些不需要使用的對象、變數等        -》 管理範圍:任何繼承了NSObject的對象。對其他基礎資料型別 (Elementary Data Type)(int、char、float、double、struct、enum等)無效        局部變數都放在了記憶體中的棧空間中,對象放在堆空間中    堆空間中的東西是動態分配的,需要我們手動回收。棧空間不用我們自己管       2、對象的基本結構         每個OC對象都有自己的引用計數器,是一個整數,表示"對象被引用的次數",即有多少人正在使用這個OC對象。(分配4個位元組的儲存空間存放引用計數器)。當對象剛剛產生的時候引用計數器是1         3、引用計數器的作用        當使用alloc、new或者copy建立一個新對象時,新對象的引用計數器預設是1             當一個對象的引用計數器值為0是,對象佔用的記憶體就會被系統回收。換句話說,如果對象的計數器不為0,那麼在整個程式運行過程,它佔用的記憶體就不可能被回收,除非整個程式已經退出。         4、引用計數器的操作         -》給對象發送一條retain訊息,可以使引用計數器值 +1 (retain方法返回對象本身)         -》給對象發送一條release訊息,可以使引用計數器值 -1 (沒有傳回值)         -》可以給對象發送 retainCount訊息,獲得當前的引用計數器值         關閉ARC(Automatic Reference Counting):            選中項目名稱→Building Settings→Levels→Apple LLVM 6.0 -Language -Objective C將下面的YES改為no                 NSUInteger:相當於long,輸出的時候預留位置使用%ld             殭屍對象:引用計數器變成0的對象,將不能使用,稱為殭屍對象     野指標:指向殭屍對象(不可用記憶體)的指標,給野指標發送訊息會報錯     null 指標:沒有指向任何東西的指標(儲存的東西是nil、NULL、0),給null 指標發送訊息不會報錯    錯誤: EXC_BAD_ACCESS:訪問了一塊壞的記憶體(已經被回收、已經停用記憶體);        為了防止訪問壞記憶體的錯誤,我們可以在對象的計數器的值減為0之後,將指標賦空值     p=nil;//將指標p變成null 指標     OC中不存在null 指標錯誤,給null 指標發送訊息,不會報錯         -[Person setAge:]: message sent to deallocated instance 0x100202230         給已經釋放的對象發送了一條setAge:訊息       5、對象的銷毀        -》當一個對象的引用計數器值為0時,那麼他將被銷毀,其佔用的記憶體被系統回收        -》當一個對象被銷毀時,系統會自動向對象發送一條dealloc訊息        -》 一般會重寫dealloc方法,在這裡釋放相關資源,dealloc就像對象的遺言        -》 一旦重寫了dealloc方法,就必須調用[super dealloc],並且放在最後面調用        -》 不要直接調用dealloc方法        -》一旦對象被回收,它佔用的記憶體就不能再用,堅持使用會導致程式崩潰(野指標錯誤)   記憶體管理原則     對對象進行一次retain,那麼使用結束的時候就要release     誰建立,誰release。如果你通過alloc、new建立一個對象,那麼你必須調用release     誰retain,誰release。只要你調用了retain,無論這個對象是如何產生的,你都要調用release        你想使用(佔用)某個對象,就應該讓對象的計數器+1(讓對象做一次retain操作)    你不想再使用(佔用)某個對象,就應該讓對象的設計器-1(讓對象做一次release)        在類的實現中擷取成員變數值方法:        _speed:直接存取成員變數        self->_speed:直接存取成員變數        self.speed:get方法        [self speed]:get方法         記憶體管理代碼規範:         1、只要調用了alloc,必須有release(aotorelease)                如果對象不是通過alloc產生的,就不需要release         2、set方法的代碼規範                 -》基礎資料型別 (Elementary Data Type):直接賦值                     - (void)setAge:(int)age                     {                         _age=age;                     }                 -》OC物件類型                     - (void)setCar:(Car *)car                     {                         //1、判斷是不是新傳進來的對象                         if(car != _car)                         {                             //2、對舊對象做一次release                             [_car release];                             //3、對新對象做一次retain                             _car = [car retain];                         }                     }           3、dealloc方法的代碼規範                -》一定要[super dealloc],而且要放到最後面                -》對self(當前)所擁有的其他對象做一次release             - (void)dealloc             {                 [_car release];                 [super dealloc];             }  @property的記憶體管理     @property (retain) Book *book;     產生的set方法如下:           - (void)setBook:(Book *)book
{     if(_book != book)     {         [_book release];         _book = [book retain];     } }
      1、set方法記憶體管理相關參數:        retain :release舊值,retain新值(適用於OC物件類型)        assign:直接賦值(預設,適用於非OC物件類型)        copy   :release舊值,copy新值       2、是否要產生set方法         readwrite:同時產生setter和getter的聲明、實現(預設)         readonly :只會產生getter的聲明、實現       3、多線程管理         nonatomic:產生set方法的時候不要加多線程代碼。效能高(一般就用這個)         atomic       :產生set方法的時候加多線程代碼。效能低(預設)       4、setter和getter方法的名稱                   setter:決定了set方法的名稱,一定要有一個冒號(不常用)             getter:決定了get方法的名稱   (一般用在BOOL類型)               @property int age;產生的方法名為:age,setAge:         @property (getter=abc , setter=setAbc: ) int age;             產生的方法名:get方法:abc                                     set方法:setAbc:                     long表示時間類型的時候,是從1970-01-01 00:00:00開始,一共過了多少毫秒                 循環參考:     涉及到循環參考(你中有我,我中有你),添加引用的時候使用@class  類名      1、@class的作用:僅僅告訴編譯器,某個名稱是一個類              @class Card;//僅僅是告訴編譯器,Card是一個類       2、開發中引用一個類的規範         -》在 .h 檔案中用@class來聲明類         -》在 .m 檔案中用#import來包含類的所有東西         使用@class可以提高編譯器編譯效率(當一個類被多個類引用的時候,如果類發生變化,那麼需要重新拷貝)             3、兩端循環參考解決方案:         -》一端用retain         -》一端用assign   autorelease:半自動釋放         @autoreleasepool     {//{ 開始代表建立了釋放池         Person *p = [[[Person alloc] init] autorelease];         p.age = 19;     }// }結束代表銷毀釋放池     注意:@autorelease是可以嵌套的,是以 棧(先進後出)的方式儲存的     1、autorelease的基本用法        -》會返回對象本身        -》會將對象放到一個自動釋放池中        -》當自動釋放池被銷毀時,會對池子裡面的所有對象做一次release操作        -》Person *p = [[[Person alloc] init] autorelease]; 調用完autorelease方法後,對象的計數器不變        2、autorelease的好處        -》不用在關心對象釋放的時間        -》不用再關係什麼時候調用release     3、autorelease的使用注意        -》佔用記憶體較大的對象不要隨便使用autorelease        -》佔用記憶體較小的對象使用autorelease,沒有太大影響     4、錯誤寫法        -》alloc之後調用autorelease,有又調用release                  @autoreleasepool
    {        Person *p = [[[Person alloc] init] autorelease];         [p release];    }-》連續調用多次autorelease    @autoreleasepool    {        Person *p = [[[[Person alloc] init]  autorelease] autorelease];    }
        5、自動釋放池        -》在IOS程式運行過程中,會建立無數個池子。這些池子都是以棧結果存在(先進後出)        -》當一個對象調用autorelease方法時,會將這個對象放到棧頂的釋放池            6、自動釋放池的建立方式        -》IOS5.0前
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];    Person *pp = [[[Person alloc] init] autorelease];    [pool release];
        -》ios5.0開始             @autoreleasepool
    {        Person *p = [[[[Person alloc] init] autorelease] autorelease];    }
      1、系統內建的方法裡沒有包含alloc、new、copy,說明返回的對象都是autorelease的        NSString *str = @"13423";這種方式建立出來的字串對象,預設就是autorelease的。不需要我們去管理記憶體     2、開發中經常會提供一些類方法,快速建立一個已經autorelease過的對象         -》建立對象時不要直接使用類名,一般用self          + (id)person
{    return [[[self alloc] init] autorelease];}
 總結:    一、計數器的基本操作            retain:+1            release:-1            retainCount:獲得計數器             二、set方法的記憶體管理        -》set方法的實現
        - (void)setCar:(Car *)car        {            if(_car != car)            {                [_car release];                _car = [car retain];            }        }
            -》dealloc方法的實現
        - (void)dealloc        {            [_car release];            [super dealloc];        } 
    三、@property參數            -》OC對象            @property (nonatomic, retain) 類名 *屬性名稱;            @property (nonatomic, retain) Car *car;            @property (nonatomic,retain) id car;             被retain過的屬性,必須在dealloc方法中release屬性                        -》非OC對象            @property (nonatomic,assign) 類型名稱 屬性名稱;            @property (nonatomic,assign) int age;     四、autorelease        -》系統內建的方法中,如果不包含alloc、new、copy,那麼這些方法返回的對象都已經autorelease過的            [NSString stringWithForm:.........]            [NSDate date];         -》開發中經常寫一些類方法快速建立一個autorelease的對象            建立對象的時候不要直接使用類名,使用self 

Objective-C:07_記憶體管理

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.