Ben Thompson
Ben Thompson

Reputation: 4833

Error on coredata viewcontrollers

I have a Core Data stack in which there are two entities: 'Client' and 'Car'. Both are represented by tableViewControllers.

The first tableViewController fetches the list of clients and then once selected, the second displays a list of cars that client owns. Both are pushed onto a navigation controller. When I go 'back' from the second viewcontroller the program shows the firstviewcontroller successfully, waits a second or so then crashes. When I did a 'build and debug' the console gave this error:

Program received signal:  “EXC_BAD_ACCESS”.

I dont understand it. Where should I look to find the error?

EDIT:I have included some code below to see if it is due to bad memory handling... I have deleted all commented out methods and as well as those not used before error crops up.

This is my ClientListViewController...

@implementation ClientListViewController

@synthesize clientsArray;
@synthesize coreDataModel;

#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];

    // Set the title
    self.title=@"Clients";

    [self populateTable];
}

-(void)populateTable {

    [self setClientsArray:[coreDataModel retrieveClientList]];

}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Override to allow orientations other than the default portrait orientation.
    return YES;
}


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [clientsArray count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...

    Client *client = (Client *)[clientsArray objectAtIndex:indexPath.row];
    cell.textLabel.text = [client name];

    return cell;

    [client release];


#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Create and push new view controller.
    ClientCarsViewController *clientCarsViewController = [[ClientCarsViewController alloc] initWithNibName:@"ClientCarsViewController" bundle:nil];

    //Pass the CoreDataModel to the view controller
    clientCarsViewController.coreDataModel = coreDataModel;

    // Pass the selected object to the new view controller
    Client *client = (Client *)[clientsArray objectAtIndex:indexPath.row];
    clientCarsViewController.client = client;

    // Push the new viewController
    [self.navigationController pushViewController:clientCarsViewController animated:YES];

    // Release the objects
    [clientCarsViewController release];
    [client release];

}


#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Relinquish ownership any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    self.clientsArray = nil;
}


- (void)dealloc {

    [clientsArray release];
    [coreDataModel release];
    [super dealloc];

}


@end

This is my ClientCarsViewController implementation...

@implementation ClientCarsViewController

@synthesize carsArray;
@synthesize coreDataModel;
@synthesize client;


#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = client.name;

    // Get client's cars
    NSSet *cars = client.cars;

    // Import them into the carsArray
    [self setCarsArray: [NSMutableArray arrayWithArray:[cars allObjects]]];

    [cars release];

}

-(void)addCarToClient {

    [coreDataModel addCarToClient:(Client *)client];

}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Override to allow orientations other than the default portrait orientation.
    return YES;
}


#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [carsArray count];

}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    Car *car = (Car *)[carsArray objectAtIndex:indexPath.row];
    cell.textLabel.text = [car carName];
    return cell;

    [car release];

}


#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.

}


#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Relinquish ownership any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    self.carsArray = nil;
}


- (void)dealloc {

    [self.client release];
    [self.coreDataModel release];
    [self.carsArray release];
    [super dealloc];
}


@end

Upvotes: 0

Views: 81

Answers (1)

sch
sch

Reputation: 27506

You are releasing objects you don't own. Have o look at Objective-C Memory Management Rules.

For example, when you obtain an object client like this:

Client *client = (Client *)[clientsArray objectAtIndex:indexPath.row];

You don't own it and should not release it.

Upvotes: 1

Related Questions