2010-06-08 73 views
0

即時通訊對於Objective-C來說相當新穎,但大部分內容都很清楚,但是當涉及到內存管理時,我會略微縮短。目前我的應用程序所做的是在NSURLConnection期間調用方法-(void)connectionDidFinishLoading:(NSURLConnection *)connection時,我輸入一個方法來解析某些數據,將其放入一個數組中,然後返回該數組。然而,我不確定這是否是最好的方法,因爲我沒有在自定義方法(method1,請參閱附件中的代碼)中釋放陣列。數組保留問題

下面是一個小腳本,用於更好地顯示什麼即時通訊做

.h文件中

#import <UIKit/UIKit.h> 

@interface memoryRetainTestViewController : UIViewController { 

    NSArray *mainArray; 

} 

@property (nonatomic, retain) NSArray *mainArray; 

@end 

.m文件

#import "memoryRetainTestViewController.h" 

@implementation memoryRetainTestViewController 
@synthesize mainArray; 


// this would be the parsing method 
-(NSArray*)method1 
{ 
    // ???: by not release this, is that bad. Or does it get released with mainArray 
    NSArray *newArray = [[NSArray alloc] init]; 
    newArray = [NSArray arrayWithObjects:@"apple",@"orange", @"grapes", "peach", nil]; 

    return newArray; 
} 


// this method is actually 
// -(void)connectionDidFinishLoading:(NSURLConnection *)connection 
-(void)method2 
{ 
    mainArray = [self method1]; 
} 

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)viewDidUnload { 
    mainArray = nil; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)dealloc { 
    [mainArray release]; 
    [super dealloc]; 
} 


@end 
+0

的,如果你只是有__ [NSArray的頁頭] INIT]的方式__該項目不保留既不自動釋放。所以它不會被泄漏到內存中,只會在功能範圍外被釋放。雖然如果使用__ [帶有Objects的NSArray數組:..] __,它將很容易自動釋放,並且不需要在dealloc上釋放它。 – Jack 2010-06-08 17:00:56

+0

@Jack:這是無稽之談,你擁有通過'-alloc'創建的對象。另外,將自動釋放對象分配給ivars是不好的,當目前的自動釋放池被耗盡時,它們將被釋放,而不是當對象的生命週期結束時釋放。你肯定有一些關於手動重新計數和自動釋放的事情,我推薦閱讀「內存管理指南」。 – 2010-06-08 18:58:54

回答

2

-method1首先創建一個新的數組,然後用一個新的覆蓋它:

NSArray *newArray = [[NSArray alloc] init]; // first array, retained 
newArray = [NSArray arrayWithObjects:...]; // second array, auto-released, 
              // pointer to first one lost 

第一個數組只是在這裏泄漏。你也在泄漏存儲在伊娃裏的數組,只是使用合成的setter來避免這種情況 - 它會爲你保留和釋放。

如果您還沒有這樣做,請閱讀Memory Management Guide的Cocoa。

一個更好的版本:

- (NSArray *)method1 { 
    NSArray *newArray = [NSArray arrayWithObjects:...];  
    return newArray; 
} 

- (void)method2 { 
    self.mainArray = [self method1]; 
} 
+0

謝謝你,解釋得很好。 – cdnicoll 2010-06-08 16:12:30

2

是的,當mainArray釋放你的newArray被釋放。但是,這只是如果method2被調用一次。

我們談論的引用,這樣,如果你有

newArray = something 
mainArray = newArray 
[mainArray release] 

兩個變量將引用到只是一個NSArray*。那麼在你的情況下,newArray只是一個本地,所以沒有問題。

newArray = something 
mainArray = newArray 
newArray = something2 
mainArray = newArray <- old reference is lost 
[mainArray release] <- just something2 is released 

爲了避免這個問題,你應該確保覆蓋另一個對象的引用之前釋放mainArray

的問題,如果你叫method2出現兩次。

編輯:沒注意到你創建陣列的兩倍:)不,這不是很好..

+0

雅...這一些是回到尋址和指針在我的c + +課上學期heh。感謝您的建議和幫助。 – cdnicoll 2010-06-08 16:14:26