iOS優化內存,提高性能 之一

在本章,你將學到:
ide

  • 複習舊的手工內存管理的策略性能

  • 對象全部權策略學習

  • 基於舊的手工內存管理之上的新的自動內存管理優化

  • 什麼是對象的拷貝以及如何使用它spa

  • 如何恰當的使用autorelease和release方法對象

  • 複習內存測量blog


iPhone是一個內存有限的環境。可是,不少開發者要麼低估了它,要麼高估了它,所以並無利用好iPhone上的可用內存來提高性能。還有一些開發者很是擔憂iPhone上的內存和性能,以致於他們過分優化,這樣其實對代碼的可閱讀性是很是有害的,也使得往後的維護變得更加困難。
事件


爲了有效利用內存來提高性能,同時使代碼更容易閱讀,又不讓應用崩潰,你須要理解iPhone環境下的內存結構。你須要學習如何避免在內存在中過多引用對象,它可以致使內存警告和程序崩潰。你一樣須要知道什麼時候retain或release一個對象;若是在內存中的對象太少,可能會使得你的計算變得緩慢,由於你須要從新構造對象或從文件系統中加載。內存


簡單的回顧開發


本部分是學習新的自動引用計數(ARC)的一個很好的過渡。有些人可能對於轉到新的課程會有些迷惑。我但願本部分可以幫助你很是順利的過渡到新的ARC機制上。


舊的對象全部權策略


若是A對象有B對象的一個強引用,那麼A對象須要手動的release對象B,這是舊的概念。若是A對象alloc,copy,mutableCopy,new或retain對象B,那麼A對象就有了對象B的強引用。另外一方面,若是A對象沒有使用這些方法,那麼A對象擁有B對象的弱引用。


對於舊的內存管理機制,若是你的對象或方法有另外一個對象B的強引用,你有責任release或autorelease對象B。每個B對象的強引用都會使得它的引用計數加1。若是沒有任何對象擁有B對象的強引用,換句話說,B對象的引用計算爲0,B對象就會被deallocated(Listing 7.1)。


Listing 7.1. Release the Object if You Have a Strong Reference

- (void)doSomething {
       NSObject *obj = [[NSObject alloc] init];

       NSLog(@"obj: %@", obj);
       [obj release];

}



AutoRelease


autorelease方法會將對象發送到一個池中,而後聲明這個對象稍後將要被release掉。使用這個方法,你不想擁有任何對象的強引用,可是你也不想它被dellocated。請查看Listing 7.2 。


Listing 7.2. Memory Issue

  • -  (NSObject *)getObj {
           NSObject *obj = [[NSObject alloc] init];

  •        return obj;

    }

  • -  (void)anotherMethod {
           NSObject *myObj = [self getObj];
           // do something
           // Should I release the object here?

  •       [myObj release];

    }


如今,在你使用完一個對象後,你要問問本身是否須要release它。一般,你可能會認爲要release它;不然,沒人release它,那麼就會發生內存泄露。可是,由於你的anotherMethod方法沒有myObj的強引用,你不能release myObj。惟一的辦法就是像Listing 7.3 使用autorelease。


Listing 7.3. Use Autorelease to Solve the Problem

  • -  (NSObject *)getObj {
       NSObject *obj = [[NSObject alloc] init];

  •    return [obj autorelease];

    }

  • -  (void)anotherMethod {
       NSObject *myObj = [self getObj];

  •    // do something

    }



注意:anotherMethod沒有其餘對象的強引用。



Autorelease


我會快速的帶你複習一下autorelease pools,而後深刻的解釋一下相關概念,這樣你就可以理解autorelease pool和release之間的不一樣。


autorelease pool是存放autoreleased對象的地方。當這個autorelease pool被release時,全部的autoreleased對象會發送一個release消息。若是一個對象的引用計數爲0,那個這個對象就會被deallocted。


在事件聲明週期結束的時候,autorelease pool會被release。例如,當用戶觸摸了UI,一個新的事件聲明週期會被建立來處理此次觸摸事件,而後它處理相關觸摸事件的全部理解,最後顯示給用戶。這就是一個事件聲明週期。對於這個事件聲明週期,你會有一個autorelease poo。


在main 方法中建立一個main autorelease pool,可使用下面的代碼:


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

      @autoreleasepool {
           int retVal = UIApplicationMain(argc, argv, nil, nil);

       }

        return retVal;

  2. }


在代碼中能夠看到,在方法的開始部分,建立了一個新的autorelease pool,使用了UIApplicationMain處理了主要的邏輯;在事件循環以後,pool被release。整個週期如圖7-1.


相關文章
相關標籤/搜索