蘋果開發教程 Cocoa記憶體管理筆記

來源:互聯網
上載者:User

蘋果開發教程 Cocoa記憶體管理筆記是本文要介紹的內容,內容分為兩種方式進行介紹,我們來看詳細內容。

下面的這種方式是不對的

 
  1. Instance you don’t own is sent release- (void)reset {NSNumber *zero = [NSNumber numberWithInteger:0]; 

建立的是一個autorelease的對象[self setCount:zero];[zero release];//這裡釋放是危險的}

 
  1. When you add an object to a collection such as an array, dictionary, or set, the collection takes ownership of 

it.在集合中增加object,那麼這個object的所有者就變成了集合了

代碼

 
  1. // ...for (i = 0; i < 10; i++) {NSNumber *convenienceNumber = [NSNumber numberWithInteger:i];  
  2. [array addObject:convenienceNumber];  
  3. }  
  4. //這種情況不需要releaseNSMutableArray *array;NSUInteger i;  
  5. // ...for (i = 0; i < 10; i++) {NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger: i]  
  6. ;[array addObject:allocedNumber];[allocedNumber release];}  
  7. //這種情況需要,此處只是將retain的計數減1而已 

安全返回對象

下面兩種方式是正確的

 
  1. (NSString *)fullName {    
  2.  NSString *string = [NSString stringWithFormat:@"%@ %@", firstName, lastName];    
  3.  return string;    
  4.  }    
  5.      
  6.  (NSString *)fullName {    
  7.  NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,    
  8.  lastName] autorelease];    
  9.  return string;    
  10.  }  

相反,下面的方式是錯誤的

 
  1.  (NSString *)fullName {    
  2.  NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,    
  3.  lastName] release];    
  4.  return string;    
  5. }   

8 同樣,下面的方式也是錯的

 
  1. (NSString *)fullName {    
  2. NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName,    
  3. lastName];    
  4. return string;    
  5. }   

對象拷貝機制

有兩種實現拷貝協議的copyWithZone:方法的方式:

使用alloc and init..

使用 NSCopyObject. 

看下面對象的定義

 
  1. @interface Product : NSObject <NSCopying> 
  2. {  
  3. NSString *productName;  
  4. float price;  
  5. id delegate;  
  6. }  
  7. @end 

拷貝後的記憶體位置圖如下:

假設從supercalass繼承了NSCopying,但是父類沒有實現NSCopying,那麼你要實現的話必須拷貝super的執行個體,同樣包括自己聲明的變數。一般情況下安全的方式是使用如alloc,
init..., and set methods

另外一方面,如果super類已經實現了NSCopying,並且在你的類中你聲明了一些執行個體變數,那麼你必須實現copyWithZone:

如果類沒有繼承NSCopying的行為,那麼實現copyWithZone: using alloc,init..., and set methods.下面是一個例子

 
  1. - (id)copyWithZone:(NSZone *)zone  
  2. {  
  3. Product *copy = [[[self class] allocWithZone: zone]  
  4. initWithProductName:[self productName]  
  5. price:[self price]];  
  6. [copy setDelegate:[self delegate]];  
  7. return copy;  

有些繼承了NSCopying behavior的類,但是他們的super類的實現可能使用了 NSCopyObject function. NSCopyObject creates an exact shallow copy of an object

by copying instance variable values but not the data they point to. 舉個例子, NSCell類採用如下的方式實現copyWithZone

 
  1. - (id)copyWithZone:(NSZone *)zone  
  2. {  
  3. NSCell *cellCopy = NSCopyObject(self, 0, zone);  
  4. /* Assume that other initialization takes place here. */  
  5. cellCopy->image = nil;  
  6. [cellCopy setImage:[self image]];  
  7. return cellCopy;  

在上面的實現採用的是淺拷貝

對可變長度的對象的拷貝實現 ,要繼承NSMutableCopying

Core Foundation Objects in Cocoa中的記憶體管理

 
  1. Core Foundation's memory allocation policy is that you need to release values returned   
  2. by functions with “Copy” or “Create” in their name; you should not release values   
  3. returned by functions that do not have “Copy” or “Create” in their name. 

舉幾個例子

 
  1. NSString *str = [[NSString alloc] initWithCharacters: ...]; ... [str release];  
  2. is equivalent to  
  3. CFStringRef str = CFStringCreateWithCharacters(...); ...  
  4. CFRelease(str);  
  5. and  
  6. NSString *str = (NSString *)CFStringCreateWithCharacters(...); ...  
  7. [str release];  
  8. and  
  9. NSString *str = (NSString *)CFStringCreateWithCharacters(...);  
  10. ... [str autorelease];  
  11. Memory Management of Nib Objects 

The File’s Owner of a nib file預設要去釋放NIB資源及頂層的對象

NIB檔案的全域擁有者是全域應用對象NSApp,但是當Cocoa應用終止時,nib中的頂層對象也沒有自動獲得dealloc訊息,因為NSApp已經被析構了。換句話說,即使nib主檔案中,你也不得不管理頂層對象的記憶體

實際上也不用擔心,mac已經有兩個特徵可以協助你了

NSWindow對象有一個isReleasedWhenClosed屬性,設定為YES則關閉視窗對象時自動關閉相關對象

nib檔案的擁有者是一個NSWindowController對象,那麼他會調用NSDocument來管理一個NSWindowController的執行個體,會自動釋放他管理的視窗的

所以現實情況就是雖然你要負責釋放一個nib檔案中的top-level對象,但是只要你的nib檔案的owner是一個NSWindowController的執行個體,那麼它會幫你釋放的。如果你的一個對象載入了nib自身並且檔案的擁有者並不是NSWindowController,那麼你可以為nib中的對象定義outlets,這樣你就可以在恰當的時候釋放他們。如果你不想為每個對象都聲明outlet,你也可以這樣:

NSNib類的instantiateNibWithOwner:topLevelObjects: 方法來獲得nib檔案中的所有頂層對象

記憶體管理總之可以歸結為:

1)你通過帶alloc,new,copy的函數建立的對象,你擁有他

2)通過retain你可以獲得擁有權

3)任何一個對象都可能有很多個owner

4)你擁有的對象你必須通過發送release或者是autorelease釋放他們

5)你不能釋放不是你擁有的對象

6)對set類型的賦值函數,你可以retain傳入的對象,你也可以copy一份,看你自己的要求咯

7)在函數(void)dealloc中一定要釋放你聲明的instance變數呀

8)指標變數使用完了一定要設為nil

9)你要確定一個對象不被釋放掉,你最好提前retain一下

10)在任何時候都不要直接調用dealloc

小結:蘋果開發教程 Cocoa記憶體管理筆記的內容介紹完了,希望本文對你有所協助!

聯繫我們

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