OC-7-內存管理

課程要點:ios

  • 內存管理的必要性
  • MRC(手動管理)
  • 自動釋放池
  • ARC是怎麼對內存進行管理的

 

    內存管理的必要性學習

   OC是一門面向對象的語言,在軟件運行過程當中會創造大量的對象,每建立一個對象系統就會給其分配一塊內存,若是開發者不對建立的這些對象進行管理,當這個軟件佔用系統20兆內存時,iPhone開始發出內存警告,若是佔用30兆內存時,iPhone OS會關閉應用程序。爲了不這種狀況咱們須要對我們建立的對象進行管理。管理方式有MRC(手動管理)、ARC(自動管理)。spa

    MRC在11年之後,漸漸的被開發者所拋棄,但爲何開發者還要學習這個東西呢。舉個例子,就比如小時候家裏的各類物品通常都是母親進行整理,咱們基本上不多管這些事,但咱們多多少少都知道母親整理物品的習慣,咱們須要找什麼東西時,只要按照母親的習慣去找就行。若是一點都不知道母親整理物品的習慣,這對咱們找東西將會很麻煩。指針

     在比較正規的公司,他們對項目的要求是很嚴格的。項目作完他們會對你作的項目進行一個內存檢測,若是太高,他們會讓你進行重構,此時若是你不知道你的項目是怎麼管理內存的,那不是就是抓瞎麼。code

 

   MRC對象

   在WWDC2011和iOS5以前,蘋果開發者一直都在使用MRC進行內存管理。blog

    由於如今Xcode建立的工程默認都是由ARC管理的。因此在使用MRC以前要關閉ARC,如圖所示繼承

     

 

     轉過MRC後看代碼:內存

     PS:我以前已經建立過Person類,因此採用下面代碼以前先在你項目裏新建一個Person類開發

#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
    /*    object-c 使用引用計數的方式管理內存。當咱們使用一個指針指向一塊內存的時候,應該對這塊內存作retain操做,那麼引用計數加一。當咱們再也不使用這個指針指向這塊內存,應該對這塊內存作release操做,那麼引用計數減一。這樣可使引用計數值一直保持等於指向這塊內存的指針數量。retainCount返回當前內存的引用計數值。當內存被開闢後,默認的引用計數爲1 。
     */

        
    //產生一個新的對象,此時不用release,由於新建的對象引用爲1,不須要爲第一個指向這個對象的指針額外加一計數。
    Person *person1 = [[Person alloc]init];
        
    NSInteger count = [person1 retainCount];
        
    //賦值後count等於1
    NSLog(@"%ld",count);
    
    
    NSObject *person2 = person1;
        
    [person2 retain];
        
    count = [person2 retainCount];
        
    //賦值後count等於2
    NSLog(@"%ld",count);
        
    //須要認識的是,不論使用object1仍是object2調用retain方法都是同樣的,由於二者指向同一塊內存,計數增長減小都是之內存爲對象的
    [person1 release],person1 = NULL;
        
    //當object2 release以後,這個對象的引用計數爲0,內存被釋放,同時會調用這個對象的delloc方法。delloc方法是每個類都有的隱式方法。當用這個類建立的對象的retainCount爲0的時候纔會調用,本身能夠在.m文件中將他重寫.若是此時你打印retainCount你會發現他的值依然是1,這裏你們只須要記住系統內部會對咱建立的對象進行操做,纔會形成這種現象。沒必要深究。
    [person2 release],person2 = NULL;
        
           
/* * object release 以後爲何還要把對象給置空 由於對象其實就是一個指針,指針指向的是一塊內存,release僅僅是把這個內存釋放了,也就是說release之後系統把這塊內存給回收了。但此時指針指向得仍是這塊內存。這是不符合邏輯的,全部我要把指針給置空,至此才切斷了這個指針與對象的全部關係。 */ } return 0; }

      輸出結果:

2015-11-27 17:47:32.162 Test[2333:228117] 1
2015-11-27 17:47:32.163 Test[2333:228117] 2
Program ended with exit code: 0

  

    重寫Person.m裏的delloc方法

#import "Person.h"

@implementation Person

//這是一個隱式方法,也就是蘋果在內部已經聲明和實現好了,若是我想要使用直接調用即可,若是想改變裏面的內容,只需在.m裏面把他重寫就行。
- (void)dealloc{
    
    NSLog(@"person對象被釋放");
    
    [super dealloc];
    
    /*
     * 爲何須要調用父類的dealloc方法
     
       子類的某些實例是繼承自父類的。所以,咱們須要調用父類的dealloc方法,來釋放父類擁有的這些對象。
     
       PS:每個類都有一個父類,用到這個類時不可避免的會用到父類裏面的東西,因此我們在子類裏釋放內存的時候,要記得經過[super dealloc]來釋放掉我們用到的父類裏面的對象。
     
       調用的順序通常來講調用的順序是,當子類的對象釋放完時,而後再釋放父類的所擁有的實例。
     
     */
}

@end

 

   輸出結果:

2015-11-27 18:13:32.355 Test[2403:238207] 1
2015-11-27 18:13:32.356 Test[2403:238207] 2
2015-11-27 18:13:32.356 Test[2403:238207] person對象被釋放
Program ended with exit code: 0

 

   自動釋放池:

  一、Autorelease pool

  自動釋放池(Autorelease pool)是OC的一種內存自動回收機制,能夠將一些臨時變量經過自動釋放池來回收統一釋放

  自動釋放池本事銷燬的時候,池子裏面全部的對象都會作一次release操做

  二、autorelease

  任何OC對象只要調用autorelease方法,就會把該對象放到離本身最近的自動釋放池中(棧頂的釋放池)。

     

       自動釋放池的使用

        //ios5.0新方式

        @autoreleasepool

       {

            //池的區域

       }

        //ios5.0以前的老方式

       NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];

           //池的區域

       [pool release];

 

       自動釋放池使用技巧:

       PS:已重寫person.m的delloc方法,並在裏面寫上NSLog(@"person對象已釋放");若是delloc方法執行,便會有輸出。

int main(){
    
    //在MRC中並非將ARC的代碼放在池中便可以自動管理內存,每建立一個對象都有在後面加上autorelease
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
    
    //不加autorelease,出池後person.m的delloc方法不會執行
    Person *person = [[Person alloc]init];
    
    [pool release];
    
}

      此時控制檯輸出:

Program ended with exit code: 0

 

     

int main(){
    
    //在MRC中並非將ARC的代碼放在池中便可以自動管理內存,每建立一個對象都有在後面加上autorelease
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
    
    //建立對象時在後面加上autorelease,出池後,person.m裏delloc方法執行
    Person *person = [[[Person alloc]init] autorelease];
    
    
    [pool release];
    
}

     此時控制檯輸出:

   

2015-11-29 14:55:02.287 Test[2757:93300] person對象被釋放
Program ended with exit code: 0

 

    

     以上是我的看法,如有錯誤歡迎指正,在學習中如有不理解歡迎騷擾 QQ:2314858225

相關文章
相關標籤/搜索