2

私には2つの問題があります。私は辞書を作成して、それを合成したグローバル変数に保存します。私はそれを割り当てるだけで、別のメソッドからアクセスしようとすると、その空で、私がコピーを使用すると、メモリがリークします。iOS NSDictionaryコピーメモリリーク

私はそれを割り当てることができます。NSStringのような "より単純な"オブジェクトがあれば動作しますが、NSDictionaryではなぜ動作しませんか?

.H:

@interface ClassIHate : UIViewController{ 
NSDictionary *postBuild; 
} 
@property (nonatomic, retain) NSDictionary *postBuild; 
-(void)prepData; 
@end 

- 私はそれだけでは私の問題であるとして、変数ポストビルドを使用するクラスを含みます。ここで問題になる可能性が何の.m

@implementation ClassIHate 
@synthesize postBuild; 

- (void)viewDidUnload { 
postBuild = nil; 
} 

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

-(void)prepData{ 
    NSInteger i = 0; 
NSMutableDictionary *_postBuild = [[NSMutableDictionary alloc]initWithCapacity:0]; 
for (NSString *key in self.keys) { 
     NSMutableArray *array = [ops valueForKey:key]; 
    NSInteger j = 0; 
     for (MyDataType *object in array) { 
    NSString *abc = object.abc; 
    UITableViewCell *cell = [table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:j inSection:i]]; 
    UITextView *tv = (UITextView *)cell.accessoryView; 
    NSString *mon = tv.text; 
    NSString *monFormat = [[NSString stringWithFormat:@"%.2lf",[mon doubleValue]]stringByReplacingOccurrencesOfString:@"." withString:@","]; 
    [_postBuild setObject:monFormat forKey:abc]; 
    j++; 
     } 
    i++; 
    } 
//postBuild = _postBuild; //Empty when called in other method 
     postBuild = [_postBuild copy]; //Leaks memory 
[_postBuild release]; 
} 

-(void)realizarOperaciones{ 
//DO STUFF 
NSArray *postKeys = [postBuild allKeys]; //postBuild is nil if I dont use copy, leaks memory if I do. 
     //DO STUFF 
} 

? ありがとう、ステファノ。

+0

これはグローバル変数ではなく、インスタンス変数です。合成された変数でもありません。あなたの例ではメソッド定義だけが合成されます。 –

答えて

3

この:

postBuild = [_postBuild copy]; //Leaks memory 
[_postBuild release]; 

は、このことが必要です。

[self setPostBuild:_postBuild]; 
[_postBuild release]; 

あなたが動作するようにして1retainCountを維持するために、このために合成セッターメソッド(however way you want)を呼び出す必要があります。

+0

うわー、それは私に遅れていた、おかげさまで、私はそれが気づかなかったことを信じていない。 – blindstuff

+0

理由は次のとおりです。最初のものは* old * postBuildオブジェクトを解放しないので、setterは自動的に宣言ごとにリークします。 – Eiko

+0

または 'self.postBuild = _postBuild' .. –

2

私は答えがすでに受け入れられていることを知っていますが、それは完全ではありません。

postBuild = [_postBuild copy]; //Leaks memory 
[_postBuild release]; 

は、メソッドを1回呼び出すだけでOKです。 prepDataに2回目以降のコールが漏れないようにするには、最初にpostBuildをリリースするか、Jacobの書き換えを使用する必要があります。 postBuildは自分が所有する_postBuildのコピーに設定され、_postBuildが正しく解放されます。

このによるリークもあります:

- (void)viewDidUnload { 
postBuild = nil; 
} 

あなたはポストビルドを所有していますが、それを解放せずにnilにそれを設定していることを覚えておいてください。これを代わりに行う必要があります:

- (void)viewDidUnload { 
    [self setPostBuild: nil]; 
} 
+0

リークがあると思います。 'prepData'が複数回呼び出されたらどうなりますか?私は 'postBuild'が少なくともコピーの前にリリースされるべきだと思います。あなたが 'viewDidUnload'も指摘しているように、リークします。 – paulbailey

+0

@paulbailey:良い点。私はそれに応じて私の答えを編集しました。 – JeremyP

+0

私はコピーしないことに決めました。代わりに、self.postBuild = _postBuildを使用しました。それはあなたが言ったことと同等だろう、そう? – blindstuff

関連する問題