Objective-C內存管理

1. Objective-C指針賦值時,retainCount不會自動增長,須要手動retain。數組

1 ClassA *obj1 = [[ClassA alloc] init];       //retain count = 1 
2 ClassA *obj2 = obj1;                             //retain count = 1 
3 [obj2 retain];                                         //retain count = 2 
4 [obj1 hello];                                           //輸出hello     
5 [obj1 release];                                     //retain count = 2 – 1 = 1 
6 [obj2 relese];             //retain count = 0,對象被銷燬                          

2. 新生成的對象只要調用autorelease就好了,無需再調用release!自動釋放的對象不須要調用release,由於已經將釋放的責任轉交給了自動釋放池。可是對於賦值的指針仍是要調用release的!函數

1 ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1 
2 ClassA *obj2 = obj1;     //retain count = 1 
3 [obj2 retain];     //retain count = 2 
4 [obj1 hello];     //輸出hello 
5                         //對於obj1,無需調用(實際上不能調用)
6 release [obj2 hello];     //輸出hello 
7 [obj2 release];     //retain count = 2-1 = 1

3. NSAutoreleasePool內部包含一個數組(NSMutableArray),用來保存聲明爲autorelease的全部對象。若是一個對象聲明爲autorelease,系統所作的工做就是把這個對象加入到這個數組中去。NSAutoreleasePool自身在銷燬的時候,會遍歷一遍這個數組,release數組中的每一個成員。若是此時數組中成員的retain count爲1,那麼release以後,retain count爲0,對象正式被銷燬。若是此時數組中成員的retain count大於1,那麼release以後,retain count大於0,此對象依然沒有被銷燬,內存泄露。spa

而自動釋放池之間以棧的形式實現:當你建立了一個新的自動釋放池時,它被添加到棧頂。接受autorelease消息的對象將被放入最頂端的自動釋放池中。若是將一個對象放入一個自動釋放池中,而後建立一個新的自動釋放池,再銷燬新建的自動釋放池,則這個自動釋放池對象仍將存在,由於容納該對象的自動釋放池仍然存在。指針

4. Objective-C程序中能夠嵌套建立多個autorelease pool。在須要大量建立局部變量的時候,能夠建立內嵌的autorelease pool來及時釋放內存。通常都是使用完對象以後立刻進行釋放,以將內存使用量保持在儘量低的水平。code

5. 若是你經過alloc、new或copy來建立一個對象,若是是臨時對象,那麼你必須在再也不使用時手動調用release或autorelease來釋放對象;若是但願在多段代碼中一直擁有對象,做爲其餘對象的實例來使用,則只需確保在擁有該對象的dealloc方法中釋放它便可。除了alloc、new或copy以外的方法建立的對象都被聲明瞭autorelease。orm

6. retain,誰release。只要你調用了retain,不管這個對象是如何生成的,你都要調用release。對象

7. 範式:Release一個對象後,當即把指針清空(順便說一句,release一個空指針是合法的,但不會發生任何事情)。blog

1 [obj1 release]; 
2 obj1 = nil;
1 ClassA *obj2 = obj1; 
2 [obj2 retain]; 
3 //do something 
4 [obj2 release]; 
5 obj2 = nil;

8. 範式:在方法中建立的臨時對象,在方法返回前須要對其進行釋放。事件

在一個函數建立並返回對象,須要把這個對象設置爲autorelease。這樣,因爲延遲釋放,返回的對象不只有效,並且保證會被自動釋放池釋放。內存

1 ClassA *Func1() 
2 3      ClassA *obj = [[[ClassA alloc]init]autorelease];  
4      return obj; 
5 }

若是程序的某個方法中須要建立不少臨時對象,當方法執行完以後這些臨時對象就沒用了。若是整個程序只有一個釋放池,則這些臨時對象會一直沒法釋放,直至事件處理結束。因此,能夠方法的開始處或循環中建立一個局部的自動釋放池,在方法返回或退出循環以前釋放自動釋放池。這樣全部該方法建立的臨時對象會隨着自動釋放池的釋放而釋放。使用@autoreleasePool{},無須顯示向某對象發送autorelease方法,全部花括號裏的代碼都會被自動放入這個新池子裏,任何在花括號裏定義的變量在括號外就沒法使用了。

 1 int main (int argc, const char *argv[]) 
 2 { 
 3      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 4      int i, j; 
 5      for (i = 0; i < 100; i++ ) 
 6      { 
 7  @autoreleasePool  8          {
 9           for (j = 0; j < 100000; j++ ) 
10              [NSString stringWithFormat:@"1234567890"];//產生的對象是autorelease的。 
12 } 13 } 14 return (0); 15 } // main

 

9. 範式:在子類的dealloc方法中調用基類的dealloc方法 。

1 -(void) dealloc 
2 { 
3 4  [super dealloc]; 
5 }

10. 範式:若是類中聲明瞭具備保持copy和複製retain特性的屬性,則須要在dealloc方法中release其成員變量

 1 @interface ClassA : NSObject 
 2  3         ClassB* _objB; 
 4 }   
 5 @property (retain) ClassB* objB; 
 6 @end   
 7 
 8 @implementation ClassA 
 9 @synthesize objB; 
10 -(void) dealloc 
11 12         [_objB release]; 13         [super dealloc]; 
14 15 @end

11. 範式:除了dealloc方法之外,始終用.操做符的方式來調用property。 

1 self.objB 或者 objA.objB

12. 本身管好本身就行。若是得到了一個其餘方法提供的對象,則不須要考慮該對象的內存管理問題,沒必要執行任何操做。可是,若是想要在一段時間內使用該對象,則須要保留retain該對象,並在使用完成後(在dealloc方法中)將其釋放release。必須保持retain方法和release方法的使用次數相等。

相關文章
相關標籤/搜索