Link to home
Start Free TrialLog in
Avatar of 154115
154115Flag for Denmark

asked on

Objective C iPhone SBJson parser memory leek when data is loaded the second time

I have a problem in my iPhone application. I'm loading points into a Google map. These points are generated from a remote JSON file. Data is loaded without problems the first time I start the application but when I select a row in the pickerview and want to change the active pins after the program is startet i get a lot of memory leeks and the program also crashes if i continue doing it. It happens when i execute this method:
[self loadMainData:@"http://mysite.com/json.php"];

I don't know why this command works the first time i load the application when the viewDidLoad method is executed but not anymore. I guess i need to empty the arrays or release the data or something? I'm hoping you experts have an idea what needs to be done and how to do it.
#import "MapperViewController.h"
#import "MyAnnotation.h"
#import "JSON.h"

@implementation MapperViewController

@synthesize mapView, btnFilter, btnRoute;

-(void) viewDidLoad
{
    [super viewDidLoad];
	
	pickerViewArray = [[NSMutableArray alloc] init];
	
	[self loadMainData:@"http://mysite.com/json.php"];
}

-(void) getJsonData: (NSString*)JsonURL
{
	//Define raw JSON string
	NSString *MyRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString: JsonURL]];
	
	if ([MyRawJson length] == 0) //If string doesn't contain any value
	{
		return; //Stop execution
	}
	
	SBJSON *parser = [[SBJSON alloc] init]; //Create parser
	list = [[parser objectWithString:MyRawJson error:nil] copy]; //Parse string
	
	[parser release];
	[MyRawJson release];
}

-(void) loadMainData: (NSString*)JsonURL
{
	[self getJsonData: JsonURL]; //Load JSON data using a method
	
	array0 = [list objectAtIndex:0]; //Define array0
	array1 = [list objectAtIndex:1]; //Define array1
	array2 = [list objectAtIndex:2]; //Define array2
	
	[mapView setDelegate:self];
	
	for(int i = 0; i < [array1 count]; i++)
	{
		//Add data to the picker view
		[pickerViewArray addObject:[array1 objectAtIndex:i]];
	}
	
    //[mapView setMapType:MKMapTypeStandard];
	[mapView setMapType:MKMapTypeHybrid];
    [mapView setZoomEnabled:YES];
    [mapView setScrollEnabled:YES];
	
    MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
	
	MyAnnotation *ann;
	
	//Get the number of pins
	int numberOfPins = [[array0 objectAtIndex:0] intValue];
	int numberOfCols = 4;
	int numberValue = 0;
	
	//Make loop to place pins
	for (int i = 0; i <= numberOfPins; i++)
	{
		if (i != 0)
		{
			ann = [[MyAnnotation alloc] init];
			
			numberValue = (numberOfCols * (i-1));
			
			region.center.latitude = [[array0 objectAtIndex:numberValue+1] floatValue]; //41.902245099708516;
			region.center.longitude = [[array0 objectAtIndex:numberValue+2] floatValue]; //12.457906007766724;
			ann.title = [NSString stringWithFormat:@"%@", [array0 objectAtIndex:numberValue+3]]; //@"Test title1";
			ann.subtitle = [NSString stringWithFormat:@"%@", [array0 objectAtIndex:numberValue+4]]; //@"Test subtitle1";
			
			[mapView setShowsUserLocation:NO];
			
			ann.coordinate = region.center;
			[mapView addAnnotation:ann];
			
			[ann release];
		}
	}
	
	region.center.latitude = 48.200001; 
	region.center.longitude = 12.300000; 
	region.span.longitudeDelta = 0.7f; 
	region.span.latitudeDelta = 0.7f;  
	[mapView setRegion:region animated:YES];
}

- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component //This method asks for what the title or label of each row will be.
{
	return [pickerViewArray objectAtIndex:row]; //We will set a new row for every string used in the array.
}

- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component //And now the final part of the UIPickerView, what happens when a row is selected.
{
	/* Remove points from map start */
	NSArray *existingpoints = mapView.annotations;
	if ([existingpoints count] > 0)
	[mapView removeAnnotations:existingpoints];
	/* Remove points from map end */

	if (row != 0)
	{
		//Reload points using the selected values
		[self loadMainData:[NSString stringWithFormat:@"http://mysite.com/json.php?category_id=%i", [[array2 objectAtIndex:row] intValue]]];
	}
	else
	{
		//Reload points using the selected values
		[self loadMainData:@"http://mysite.com/json.php"];
	}
}

Open in new window

Avatar of mad_mac
mad_mac

it looks like you have a lot of auto releasing going on with  the within the loadMainData method, you may want to consider setting up a auto release pool and draining it at the end of the loadMainData method.

in addition i think you need to look at your list variable, a simple retain rather than a copy may be better here, also your list var needs to be released and cleared before subsequent executions of the code in the getJsonData method.

if (list != nil) {
    [list release];
    list = nil;
}

Open in new window

Avatar of 154115

ASKER

I used the code you attached but the application still crashes after a while if i select items in the picker so unfortunately it didn't solve the problem to release and clear the list.

"it looks like you have a lot of auto releasing going on with  the within the loadMainData method, you may want to consider setting up a auto release pool and draining it at the end of the loadMainData method."
Could you please tell me how to do that?

in addition i think you need to look at your list variable, a simple retain rather than a copy may be better here
list = [[NSArray alloc] init]; or what is the best way?
Avatar of 154115

ASKER

If I uncomment the function call to the getJsonData method i get no error and the program will run without any problems (but with no data). For some reason this method is making the application crash but I don't know why.
ASKER CERTIFIED SOLUTION
Avatar of mad_mac
mad_mac

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of 154115

ASKER

Thank you mad_mac

It didn't solve the crash problem but it solved the memory issue. I found out i could load the data once and then load it from the arrays when i wanted to change it. Now the program don't crash anymore. Thank you for the good examples.They helped me a lot :-)
Avatar of 154115

ASKER

It solved the memory issue but the other part i solved myself. Thank you again mad_mac.