2

У меня есть две проблемы. У меня есть один метод, который создает словарь, а затем сохраняю его для глобальной переменной, которую я синтезировал. Если я просто назначу его, когда я попытаюсь получить доступ к нему из другого метода, его пустой, если я использую копию, он будет утечка памяти.iOS NSDictionary Copy Memory Leak

Я могу просто назначить его, и он работает, если его, скажем, «более простой» объект, такой как NSString, почему это не работает с NSDictionary ?.

.h:

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

I'm только включая классы, которые используют переменную postBuild, так как это моя проблема. .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

Это переменная экземпляра, а не глобальная переменная. Это также не синтезированная переменная; в вашем примере синтезируются только определения метода. – 2010-11-23 22:28:27

ответ

3

Это:

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

Должно быть так:

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

Вы должны вызвать синтезированный метод установки (however way you want) для этого, чтобы работать и держать retainCount в 1.

+0

Ничего себе, это было затормозило меня, большое спасибо, я не могу поверить, что я этого не заметил. – blindstuff 2010-11-23 20:25:43

+0

Вот почему: первая утечка вашего * старого * объекта postBuild, поскольку вы его не выпускаете, поскольку установщик автоматически выполняет объявление. – Eiko 2010-11-23 20:29:43

2

Я знаю, что ответ уже принят, но это не совсем правильно.

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

на самом деле нормально, если вы только вызываете метод один раз. Чтобы остановить его от утечки во втором и последующих звонках до prepData, вам нужно сначала выпустить postBuild или использовать переписывание Якоба. postBuild устанавливается на копию _postBuild, которую вы владеете, а _postBuild затем правильно выпущен.

Существует также утечка, вызванное этим:

- (void)viewDidUnload { 
postBuild = nil; 
} 

Помните, что у вас есть postBuild но вы просто установить его на ноль, не отпуская его. Вам нужно это сделать:

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