2010-06-04 5 views
0

J'ai j'ai deux méthodes à la fois dans différentes 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.NSArray tableau d'exécution

#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.

+0

D'où vient 'xmlObject' vient? – d11wtq

+0

En outre, 'textmeAppDelegate' est-il un type valide? Il ressemble plus au nom d'une variable d'instance qu'à un type, mais vous essayez de l'utiliser comme un type. – d11wtq

+0

xmlObject est une classe importée au début du fichier.Et textmeAppDelegate est un type valide car c'est comme ça que j'appelle délégué dans différentes parties de mon application. –

Répondre

1

J'ai plusieurs commentaires sur votre code. L'un d'entre eux est la cause immédiate de votre accident, mais vous devez également corriger au moins un autre problème. La réponse courte est que vous relâchez val et les clés.

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

Vous n'avez pas besoin de créer un nouveau tableau ici, vous pouvez simplement écrire:

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

si vous le faites, vous n'avez pas besoin [bgColor release] plus bas.

NSArray *keys = [[NSArray alloc] initWithArray:[tmp allKeys]]; 
keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 

Ces deux lignes leak la première NSArray, vous alloc, mais vous écrasez tout de suite avec la version triée. En fait, vous pouvez simplement écrire:

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

Notez que vous ne possédez pas les clés de sorte que vous pouvez vous débarrasser de la ligne [keys release] plus bas.

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

Ceci est la source de votre problème immédiat. Vous allouez d'abord une nouvelle chaîne. Ensuite, vous l'écrasez immédiatement à chaque itération de votre boucle. Ainsi, les NSString alloués fuient. Vous ne possédez pas le val retourné par [[tmp objectForKey:str] objectForKey:@"innertext"]; à chaque itération, de sorte que le ov de libération val après la boucle ne doit pas être là.

Sur une note de côté, objectForKey: retourne un identifiant - la distribution à NSString * est redondant. La plupart des gens l'ignorent. Pour en revenir au bit ci-dessus où je vous ai dit que vous étiez en train de perdre vos clés alloc'd? Eh bien, la nouvelle version des clés que vous l'avez écrasée ne vous appartient pas. Par conséquent, vous ne devez pas relâcher les clés ici.

return [NSArray arrayWithArray:pushArr]; 

C'est très bien. Ma préférence serait pour:

return [[pushArray copy] autorelease]; 

mais c'est juste une question de style. Vous pouvez également retourner pushArray, mais pushArray est modifiable et l'appelant peut compter sur la valeur de retour étant immuable.

+0

Merci un million pour la réponse et merci un billion pour résoudre le problème. Cela me rendait fou. Pouvez-vous me dire pourquoi lors du lancement de l'application, j'ai eu tellement de 'malloc: *** erreur pour l'objet 0x43181e0: double gratuit' sur la console –

+0

Très probablement, il ya beaucoup de problèmes similaires ailleurs dans votre code. Je pense que vous aurez besoin de revoir la plupart de celui-ci. – JeremyP

+0

J'ai examiné mon application avec les points ci-dessus à l'esprit et maintenant il n'y a plus que quelques fuites. Quelle pourrait être la procédure de suppression des fuites de l'application entière. –

1

Testez votre code avec jeu NSZombieEnabled ... Il devrait vous donner assez d'informations pour résoudre votre problème.

+0

J'ai activé NSZombieEnabled. pouvez-vous dire comment puis-je obtenir une raison pour l'erreur d'exécution "EXC_BAD_ACCESS" –

+0

EXC_BAD_ACCESS signifie souvent que vous envoyez un message à un objet désalloué. NSZombieEnabled placera un objet factice pour chaque objet désalloué, ce qui vous informera quand un message est passé après la désallocation. Vérifiez les journaux de votre console ... – Macmade

+0

app écrasé sur le départ avec cette console sur *** - [CFString version]: message envoyé à l'instance désaffectée 0x43385f0 –