2010-06-04 8 views
0

J'ai deux méthodes dans deux classes. L'une est la méthode de classe et l'autre est la méthode de l'instance. J'appelle la méthode de classe de la méthode d'instance. Lorsque la méthode d'instance se termine, l'erreur d'exécution "EXC_BAD_ACCESS" est générée.Numéro de désallocation NSMUtableDictionary

#import "xmlObject.h" 
#import "textmeAppDelegate.h" 

@implementation Class1 
    - (void)method1 { 
     textmeAppDelegate *del = (textmeAppDelegate *)[[UIApplication sharedApplication] delegate]; 

     NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]]; 
     UIColor *color = [UIColor colorWithRed:[[bgColor objectAtIndex:3] floatValue] green:[[bgColor objectAtIndex:2] floatValue] blue:[[bgColor objectAtIndex:1] floatValue] alpha:[[bgColor objectAtIndex:0] floatValue]]; 
     CGContextSetFillColor(context, CGColorGetComponents([color CGColor])); 
     CGContextFillRect(context, rect); 
     [bgColor release]; 

    } 
@end 

@implementation xmlObject 
    + (NSArray *) fetchImmediateChildrenValues:(NSMutableDictionary *) node { 
     NSMutableDictionary *tmp = [[node objectForKey:@"children"] retain]; 
     NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]]; 
     keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 
     NSMutableArray *pushArr = [[[NSMutableArray alloc] init] autorelease]; 
     NSString *val = [[NSString alloc] init]; 
     for(NSString *str in keys) { 
      val = (NSString *)[[tmp objectForKey:str] objectForKey:@"innertext"]; 
      [pushArr addObject:val]; 
     } 
     [val release]; 
     [keys release]; 

     return [NSArray arrayWithArray:pushArr]; 
    }   
@end 

Quel est le problème avec le code? Aussi l'application se bloque pour cette ligne de code l'application se bloque si j'insérez la ligne

NSArray *bgColor = [[NSArray alloc] initWithArray:[xmlObject fetchImmediateChildrenValues:[del.navigationbarStyle objectForKey:@"backgroundcolor"]]]; 

Si je le supprimer l'application fonctionne bien.

Répondre

1

Vous libérez des objets alors que vous ne devriez pas l'être.

Dans fetchImmediateChildrenValues ​​vous libérez val, mais ce n'est pas le même val que vous avez alloué, c'est le val retourné dans la boucle for là. Supprimez l'alloc et la publication pour val.

///NSString *val = ... 
for(NSString *str in keys) { 
    NSString* val = (NSString *)[[tmp objectForKey:str] objectForKey:@"innertext"]; 
    [pushArr addObject:val]; 
} 
///[val release]; 

Vous faites la même erreur avec les clés. Vous initialisez les clés à quelque chose que vous possédez (vous l'avez alloué) puis vous le remplacez (causant une fuite de mémoire) par quelque chose que vous ne possédez pas (autorelease), puis vous relâchez les touches qui libèrent l'objet auto-libéré. Donc vous avez fini par le libérer.

Lisez à nouveau les règles sur la gestion de la mémoire. Voir here et here.

+0

Merci qui l'a fait. maintenant est aussi en me donnant malloc: *** erreur pour l'objet 0x43181e0: double gratuit sur le lancement de l'application. Des idées pourquoi cela arrive? –

0

je crois que le problème est lié avec

keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 

dans la description de sortedArrayUsingSelector il dit qu'il renvoie des références au tableau original mais vous écrasez efficacement qu'avec l'affectation. Pour être du bon côté, attribuez plutôt une nouvelle variable (et évitez toute fuite)

+0

cette ligne est correcte. Je l'ai pris à partir de la documentation de l'iPhone. Le vrai problème est avec NSMutableDictioanry allocation correcte et deallocation –