2011-07-04 14 views
1

メソッドが呼び出された後に配列を解放する正しい方法を見つけるのが苦労しています。 I私は私の方法でacheiveしようとしているものを達成するためのより良い方法があるかどうか疑問:メモリ管理に苦しんで配列メソッドを作成

- (NSArray *) setupDetailArray : (NSString *) selectedCategory { 

    // Load .plist file 
    NSString *path = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"]; 

    // Load .plist into a new dictionary 
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path]; 

    // Drill down to next level 
    NSArray *faceSelection = [[NSArray alloc] initWithArray:[dict objectForKey:detailTitle]]; 
    [dict release], dict = nil; 

    // Set up link to App Delegate 
    UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 
    dataCenter.faces = [[NSMutableArray alloc] init]; 

    // Set app delegate faces to array 
    dataCenter.faces = faceSelection; 
    [dataCenter.faces release]; 

    return faceSelection; 

    // [faceSelection release], faceSelection = nil; ?????? 

} 

そして、私は私のアプリケーションは、ここでのメモリをリークしている

// If faceArray is empty, create it 
if (faceArray == nil) 
    faceArray = [self setupDetailArray:detailTitle]; 
... 
のviewDidLoad

の私のメソッドを呼び出すと、私は一度やったらすべてを解放する方法を本当に探しています。

答えて

2

あなたのメソッドは、オートレリーズされた配列を返す必要があります。オートレリーズされた配列は、それを保持したい/必要がある場合に呼び出すメソッドによって保持されます。

- (NSArray *) setupDetailArray : (NSString *) selectedCategory { 
... 
// Create the array, but don't own it 
NSArray *faceSelection = [[[NSArray alloc] initWithArray:[dict objectForKey:detailTitle]] autorelease]; 
... 
return facesSelected; 
} 

ここで、このメソッドを呼び出すコードでは、必要に応じてオブジェクトを保持する必要があります。だから、あなたのviewDidLoad

if (faceArray == nil) 
    faceArray = [[self setupDetailArray:detailTitle] retain]; 
... 

faceArrayは、あなたのクラスのインスタンス変数がある場合には、その後、あなたは自分のdeallocメソッドでそれを解放することができます。

また、これは私があなたが読むことをお勧め(および再読み込みと再読み込み)ドキュメントをメモリ管理上と読んだ

// Set up link to App Delegate 
    UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 
    dataCenter.faces = faceSelection; 

である必要があり、ここで

// Set up link to App Delegate 
    UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 
    dataCenter.faces = [[NSMutableArray alloc] init]; 

    // Set app delegate faces to array 
    dataCenter.faces = faceSelection; 
    [dataCenter.faces release]; 

メモリリークしていますプロパティ、セッター、ドット表記法などがあります。素敵な事が行われるべきかを知って - - すなわち、すべてのメソッドが特定の状況を除き、自動解放を返すべき興味深い

Apple Objective-C Memory Management

+0

よろしくお願いいたします。私は完全に新しいので、私はその文書と闘う。私はいつかそれが意味をなさないと信じています! – squarefrog

+0

あなたはそれを何度も何度も読んで、可能な限り多くの例を見つけようとする必要があります。結局それは意味をなさない! –

+0

自信を持って投票してくださったNick Bull! – squarefrog

1
dataCenter.faces = [[NSMutableArray alloc] init]; 

あなたは非自動解放配列を割り当て、(私はそれがretain修飾子を持っている賭ける)プロパティfacesに割り当てます。

dataCenter.faces = faceSelection; 

今、あなたはfacesプロパティに新しい配列として割り当てていますが、正しく以前NSMutableArrayのを解放していません。

[dataCenter.faces release]; 

あなたは今、間接的にあなたのfaceSelection配列を解放します。

このメソッドを実行するたびに、少なくとも1つのNSMutableArrayがリークします。

// Drill down to next level 
NSArray *faceSelection = [[dict objectForKey:detailTitle] copy]; 
[dict release], dict = nil; 

// Set up link to App Delegate 
UltimateRageAppDelegate *dataCenter = (UltimateRageAppDelegate *) [[UIApplication sharedApplication] delegate]; 

// Set app delegate faces to array 
dataCenter.faces = faceSelection; 

return [faceSelection autorelease]; 

このメソッドでは、自動解放されたオブジェクトが返されます。

  • 開始alloc
  • 開始とnew
  • と自動解放オブジェクトを返す必要がありcopy

他のすべてのメソッドが含まれています:オブジェクトを保持して返さなければなら唯一の方法は、メソッド、名前があります。

+0

。私は問題を抱えていますが、このコードを再利用するとき、マスタービューに戻って別の行をクリックすると、dataCenter.faces = faceSelectionを設定しようとするとEXC_BAD_ACCESSになります。 – squarefrog

1

これを行うための他の方法。

//Declare method as follows. 
- (void) setupDetailArray : (NSString *) selectedCategory arrFaceArray:(NSArray *)faceArray 
{ 
} 

そして私はまた、自動解放オブジェクトを維持するため@DarkDustの答えを考える

if (!faceArray) 
{ 
    faceArray = [[NSArray alloc] init]; //Alloc in ViewDidLoad and release in ViewDidUnload or dealloc. 
    faceArray = [self setupDetailArray:detailTitle arrFaceArray:faceArray]; 
} 

のviewDidLoad

に私のメソッドを呼び出します。どちらも可能な方法です。

+0

私はこの答えをよく理解していません。 voidメソッドは配列オブジェクトをどのように返しますか? – squarefrog

+0

@squarefrogここでは参照を渡しているので、配列を返す必要はなく、その配列に参照として渡される項目を追加します。ゴッチャ? –

+0

右!説明してくれてありがとう。 – squarefrog