2

J'ai deux problèmes, j'ai une méthode qui construit un dictionnaire, puis je l'enregistre dans une variable globale que j'ai synthétisée. Si je l'assigne juste, quand j'essaye d'y accéder d'une autre méthode, son vide, si j'emploie la copie, il fuit la mémoire.iOS NSDictionary Copier la fuite de mémoire

Je peux juste l'assigner et cela fonctionne si c'est, disons, un objet "plus simple" comme un NSString, pourquoi cela ne fonctionne-t-il pas avec NSDictionary ?.

.h:

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

je suis seulement, y compris les classes qui utilisent la Postbuild variable, comme c'est ma question. .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 
} 

Quel pourrait être le problème ici? Merci, Stefano.

+0

C'est une variable d'instance, pas une variable globale. Ce n'est pas non plus une variable synthétisée; Seules les définitions de méthode sont synthétisées dans votre exemple. –

Répondre

3

Ce:

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

devrait être ceci:

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

Vous devez appeler la méthode setter synthétisé (however way you want) pour que cela fonctionne et pour maintenir le retainCount à 1.

+0

Wow, ça a été retardé de moi, merci beaucoup, je ne peux pas croire que je n'ai pas remarqué ça. – blindstuff

+0

Voici pourquoi: le premier fuit votre objet * old * postBuild, puisque vous ne le libérez pas - comme le setter le fait automatiquement par déclaration. – Eiko

+0

Ou faire 'self.postBuild = _postBuild' .. –

2

Je sais qu'une réponse a déjà été acceptée, mais ce n'est pas tout à fait correct.

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

est réellement OK si vous n'appelez la méthode qu'une seule fois. Pour l'empêcher de fuir lors des appels suivants, prepData, vous devez d'abord libérer postBuild ou utiliser la réécriture de Jacob. postBuild est défini sur une copie de _postBuild que vous possédez et _postBuild est alors correctement libéré.

Il y a aussi une fuite causée par ceci:

- (void)viewDidUnload { 
postBuild = nil; 
} 

Rappelez-vous que vous possédez Postbuild mais vous avez mis juste à zéro sans le relâcher. Vous devez faire cela à la place:

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

Je pense que ça fuit. Que se passerait-il si 'prepData' était appelé plus d'une fois? Je pense que 'postBuild' devrait au moins être publié avant la copie. Comme vous le faites remarquer 'viewDidUnload' fuit également. – paulbailey

+0

@paulbailey: Bon point. J'ai édité ma réponse en conséquence. – JeremyP

+0

J'ai décidé de ne pas copier, j'ai plutôt utilisé self.postBuild = _postBuild, dans la vue did décharger im faisant self.postBuild = nil; ce serait l'équivalent de ce que vous avez dit, n'est-ce pas? – blindstuff