views:

161

answers:

3

Hi, i wrote the following code :

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]; 

the rows are json response parsed by jsonlib this string is returned to a viewcontroller that loads it into a webview ,but i keep getting exc_bad_access for this code on completion of the method that calls it , i don't even have to load it to the webview just calling this method and not using the nsstring causes the error on completion of the calling method... any help will be apperciated thanks .

- (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];
}

with or without the release , it doesn't matter

+3  A: 

Your memory management is wrong.

Change:

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

to:

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

Then change:

return [table autorelease];

to:

return table;

The reason is the table you're autoreleasing at the end is the one constructed by the previous line:

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

You're therefore autoreleasing this twice (stringByAppendingString: returns an autoreleased instance), and not releasing the original table at all.

Steven Fisher
doesn't seems to work , still getting exec_bad_access
amnon
@amnon: You also need to not release the string in the calling method. Then it should work. If not, post your revised code, because what tewha said should work.
Chuck
Thanks , that did the trick the exec_bad_access that i was getting after this was because of an error in handling the nsmutablerequest object for the json request , it took some time hunting it down but malloc_history did it ... thanks everyone
amnon
amnon, the longer you go without understanding iPhone/Mac OS X memory management, the more code you'll have to correct. Make sure you read Apple's text on it. You probably won't understand it entirely yet, but you'll be a lot closer. :)
Steven Fisher
A: 

Regarding the update, if you correctly incorporated tewhas suggestions, -fetchTable:psw: returns an autoreleased NSString, thus you shouldn't release it in the calling method:

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

-fetchTable:psw: should handle table like this:

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

// ... leave the rest as it is

return table;

Note that you are also leaking json_string, you should -release or -autorelease it.

Georg Fritzsche
A: 

How about constructing the table using an NSMutableString? One problem with your current approach is that you'll flood the autorelease pool unnecessarily.

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;
dreamlax