2010-05-25 3 views
0

i écrit le code suivant:NSString, EXC_BAD_ACCESS et stringByAppendingString

NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; 
NSDictionary *reportDic = [jsonparser objectWithString:json_string error:nil]; 
NSDictionary *reporttable = [reportDic objectForKey:@"reporttable"]; 
NSArray *rows = [reporttable objectForKey:@"rows"]; 


NSString *table = [[NSString alloc]initWithString:@"<table>"] ; 
for (NSDictionary *row in rows) 
{ 

    table = [table stringByAppendingString:@"<tr>"]; 

    NSArray *cells = [row objectForKey:@"cells"]; 
    for (NSString *cell in cells){ 
     table = [table stringByAppendingString:@"<td>"]; 
     table = [table stringByAppendingString:cell]; 
     table = [table stringByAppendingString:@"</td>"]; 
    } 

    table = [table stringByAppendingString:@"</tr>"]; 
    index++; 
} 
table = [table stringByAppendingString:@"</table>"]; 
return [table autorelease]; 

les lignes sont réponse JSON analysées par jsonlib cette chaîne est retournée à un viewcontroller qu'il charge dans une WebView, mais je continue à me EXC_BAD_ACCESS pour ce code à la fin de la méthode qui l'appelle, je n'ai même pas à le charger sur le webview juste en appelant cette méthode et ne pas utiliser le nsstring provoque l'erreur à la fin de la méthode d'appel ... toute aide sera apperciated merci .

- (void)viewDidLoad { 

[super viewDidLoad]; 

AMAppDelegate *appDelegate = (AMAppDelegate*)[[UIApplication sharedApplication] delegate]; 
NSString * data = [appDelegate fetchTable:name psw:psw]; 

[webView loadHTMLString:@"this is html" baseURL:nil]; 
[data release]; 
} 

avec ou sans la libération, il n'a pas d'importance

+0

Ensuite, vous devez publier la méthode d'appel. – Yuji

Répondre

4

Votre gestion de la mémoire est mauvaise.

Change:

NSString *table = [[NSString alloc]initWithString:@"<table>"] ; 

à:

NSString *table = [[[NSString alloc]initWithString:@"<table>"] autorelease]; 

changer ensuite:

return [table autorelease]; 

à:

return table; 

La raison en est la table que vous êtes autoreleasing à la fin est celle construite par la ligne précédente:

table = [table stringByAppendingString:@"</table>"]; 

Vous autoreleasing donc cette fois (stringByAppendingString: renvoie une instance autoreleased), et ne pas libérer la table d'origine du tout.

+0

ne semble pas fonctionner, en obtenant toujours exec_bad_access – Amnon

+0

@amnon: Vous devez également ne pas libérer la chaîne dans la méthode appelante. Alors ça devrait marcher. Si ce n'est pas le cas, affichez votre code révisé, car ce que dit tewha devrait marcher. – Chuck

+0

Merci, cela a fait l'affaire exec_bad_access que je recevais après une erreur dans le traitement de l'objet nsmutablerequest pour la requête json, ça a pris un peu de temps à le rattraper mais malloc_history l'a fait ... merci tout le monde – Amnon

0

En ce qui concerne la mise à jour, si vous y avez incorporé correctement suggestions de tewhas, -fetchTable:psw: retourne un autoreleasedNSString, donc vous ne devriez pas le libérer dans la méthode d'appel:

NSString *data = [appDelegate fetchTable:name psw:psw] 
// ... 
[data release]; // don't do that, data is autoreleased 

-fetchTable:psw: devrait gérer table comme ceci:

NSString *table = [NSString stringWithString:@"<table>"] ; 

// ... leave the rest as it is 

return table; 

Notez que vous avez aussi des fuites json_string, vous devriez -release ou -autorelease il.

1

Que diriez-vous de construire la table en utilisant un NSMutableString? Un problème avec votre approche actuelle est que vous inonderez inutilement le pool autorelease.

NSMutableString *table = [NSMutableString string]; 

[table appendString:@"<table>"]; 
for (NSDictionary *row in rows) 
{ 
    [table appendString:@"<tr>"]; 

    NSArray *cells = [row objectForKey:@"cells"]; 
    for (NSString *cell in cells){ 
     [table appendFormat:@"<td>%@</td>", cell]; 

    [table appendString:@"</tr>"]; 

    index++; 
} 
[table appendString:@"</table>"]; 
return table;
+0

Avait un cas similaire lors de la construction d'un fichier CSV. Cela l'a résolu! – Christoph