Convolution
Convolution

Reputation: 2351

SBJSON Parser Memory Leak

I'm trying to parse a JSON feed using SBJSON but every time I run it through instruments I get a 100% memory leak on one line. I definitely have something incorrect and was hoping for some insight.

I have a tableview of Towns and as you click on a town, this feed will run and grab a list of people who live in the town and parse them in a tableview. However, everytime I pop the details view back to the list of towns and go into a new details view I end up with memory leaks

 SBJsonParser *parser = [[[SBJsonParser alloc] init] autorelease];
            NSString *jsonString = [[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding];

        id response = [parser objectWithString:jsonString error:NULL]; //100.0% memory leak

        NSMutableDictionary *peopleDictionary = (NSMutableDictionary *)response;

        NSMutableArray *buildingArray = [[NSMutableArray alloc] init];

        if (peopleDictionary != nil) {
            for (NSDictionary *dict in peopleDictionary) {  
                Person *incoming = [[Person alloc] init];
                incoming.firstName = [dict objectForKey:@"firstName"];
                incoming.lastName = [dict objectForKey:@"lastName"];
                incoming.address = [dict objectForKey:@"address"];
                [buildingFeedArray addObject:incoming];
                [incoming release];
            }
        }
        [jsonString release];
        self.peopleArray = buildingFeedArray;
        [self.tableView reloadData];
        [buildingFeedArray release];

Upvotes: 2

Views: 2339

Answers (1)

Jonathan.
Jonathan.

Reputation: 55554

You have created an NSArray called buildingArray, but then added objects to buildingFeedArray, and released buildingFeedArray.

You need to change line 5:

NSMutableArray *buildingArray = [[NSMutableArray alloc] init];

To:

NSMutableArray *buildingFeedArray = [[NSMutableArray alloc] init];


You should release objects as soon as possible, so in the code you posted you have not used jsonString after parsing, so you should release it directly after.


Also you can simplify the code by replacing:

SBJsonParser *parser = [[[SBJsonParser alloc] init] autorelease];
NSString *jsonString = [[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding];
id response = [parser objectWithString:jsonString error:NULL]; //100.0% memory leak
NSMutableDictionary *peopleDictionary = (NSMutableDictionary *)response;

With:

NSString *jsonString = [[NSString alloc] initWithData:[request responseData] encoding:NSUTF8StringEncoding];
NSDictionary *peopleDictionary = (NSDictionary *)[jsonString JSONValue];

JSONValue is convenience method added to NSString by the SBJSON framework,

And you haven't modified peopleDictionary in your code, so it does not need to be mutable.
Also the SBJSON framework, whether you use the convenience method or not, does not return mutable objects, so should you have attempted to use a method of the mutable class, the compiler would not have warned you but the app would have crashed when you reached it.

Upvotes: 1

Related Questions