2010-12-06 24 views
0

J'ai rencontré une fuite lorsque j'ai tenté de charger des objets personnalisés enregistrés à partir de NSUserDefaults. Voici le code qui est le coupable. Est-ce que quelqu'un voit quelque chose qui est clairement faux?Fuite de mémoire pour decodeObjectForKey dans l'objet personnalisé

@interface CustomQuery : NSObject <NSCoding> { 
NSString *theTitle; 
NSString *query; 
} 

@property(nonatomic, retain) NSString *theTitle; 
@property(nonatomic, retain) NSString *query; 

- (id)initWithCoder:(NSCoder *)aDecoder { 

if (self = [super init]) { 
    //tempTitle is leaking 
    NSString *tempTitle = [[aDecoder decodeObjectForKey:@"QueryTitle"] retain]; 
    self.theTitle = tempTitle; 
    [tempTitle release]; 

    //tempQuery is leaking 
    NSString *tempQuery = [[aDecoder decodeObjectForKey:@"QueryValue"] retain]; 
    self.query = tempQuery; 
    [tempQuery release]; 
} 
return self; 
} 

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

C'est aussi dans la liste comme une fuite dans Instruments

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults]; 
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedQueries"]; 
if (dataRepresentingSavedArray != nil) 
{ 

    //This is Leaking in Instruments 
    NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray]; 
    if (oldSavedArray != nil) { 

     //tempCustomQueryArray is also leaking 
     NSMutableArray *tempCustomQueryArray = [[NSMutableArray alloc] initWithArray:oldSavedArray]; 
     if (savedQueries != nil) { 
      savedQueries = nil; 
     } 
     self.savedQueries = tempCustomQueryArray; 
     [tempCustomQueryArray release]; 
    } 
} 

Répondre

2

Dans ce:

NSString *tempTitle = [[aDecoder decodeObjectForKey:@"QueryTitle"] retain]; 
self.theTitle = tempTitle; 
[tempTitle release]; 

Le retain et release ne sont pas nécessaires parce que votre propriété sera retain l'objet. Cependant, je pense que ces deux cordes sont un hareng rouge; il est probable que la fuite est ailleurs.

Je soupçonne que savedQueries n'est pas publié dans le dealloc que je suppose ne pas être montré. Cela s'accrocherait aux questions et à un tas d'autres choses.

Cela n'explique pas entièrement d'où provient la fuite de oldSavedArray (à moins que je ne manque quelque chose).

Activez le suivi de conservation/relâchement dans l'instrument d'allocation et voyez où chaque conservation/libération est appelée. Vous trouverez un déséquilibré quelque part.

J'ai écrit un blog post qui est liée et qui pourrait être utile.

+0

Merci pour l'aide, je vais activer ces fonctionnalités et voir si je peux trouver des informations plus significatives. – aahrens

+0

Après avoir regardé plus en détail, j'avais raté une erreur évidente. Le code ci-dessus qui initialisait oldSavedArray était à la fois dans ma méthode viewDidLoad et dans la méthode viewWillAppear. Merci pour votre aide – aahrens

0

Je ne vois pas où vous avez implémenté la méthode de délégation encodeWithCoder ou comment vous archivez (enregistrement dans NSUserDefaults). Je voudrais également essayer de modifier vos méthodes CustomQuery.m pour refléter:

- (void)encodeWithCoder:(NSCoder *)encoder 
{ 
    [encoder encodeObject:self.theTitle forKey:@"QueryTitle"]; 
    [encoder encodeObject:self.query forKey:@"QueryValue"]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 

    self = [super init]; 
    self.theTitle = [aDecoder decodeObjectForKey:@"QueryTitle"]; 
    self.query = [aDecoder decodeObjectForKey:@"QueryValue"]; 

    return self; 
} 
+0

J'appelle [[NSUserDefaults standardUserDefaults] setObject: [NSKeyedArchiver archivéDataWithRootObject: savedQueries] forKey: @ "savedQueries"]; enregistrer mes objets personnalisés – aahrens