I'm facing some sort of memory related issue I cannot figure out.
In a summary view, I'm creating a tableview populated by an array (sectionArray) which in turn is loaded from a core data repository. This array of NSManaged objects is used to assign values to a custom UITableViewCell which has two labels: title and description.
When the user clicks on a row, this loads a detail view where you can edit the values and save them to the database. The summary view passes the detail view an NSManagedObject reference (settingObject) in order to know what record in the core data database was selected and must be updated.
The problem is that once the value is updated in the detail view in this NSManagedObject, when the tableview information in the summary view is reloaded, I get a EXC_BAD_ACCESS exactly in the point where the label information is read from the sectionArray.
Here are some excerpts from my code: the summary view .h and .m and the detail view .m.
I guess it's related to the release of the sectionArray or settingObject being used, but I tried different approaches and no solution yet. The Bad Access error keeps occurring at the same point (identified below in the code).
I thank any help.
// SettingsViewController.h
#import "DataHelper.h"
@interface SettingsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
UITableView *settingsTableView;
SettingsDetailViewController *settingsDetailViewController;
NSManagedObjectContext *managedObjectContext;
NSMutableArray *sectionArray;
}
@property (nonatomic, retain) IBOutlet UITableView *settingsTableView;
@property (nonatomic, retain) SettingsDetailViewController *settingsDetailViewController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSMutableArray *sectionArray;
@end
// SettingsViewController.m
#import "SettingsViewController.h"
#import "SettingsCellController.h"
#import "SettingsDetailViewController.h"
@implementation SettingsViewController
@synthesize settingsTableView;
@synthesize settingsDetailViewController;
@synthesize managedObjectContext;
@synthesize sectionArray;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
-(void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"Settings";
// Get the managed object context from the delegate
ApplicationAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
managedObjectContext = delegate.managedObjectContext;
}
-(void)viewWillAppear:(BOOL)animated {
// Get information to populate UICustomTableViewCell
[self setSectionArray:[DataHelper searchObjectsInContext:@"Sections" :nil :@"Id" :YES :managedObjectContext]];
// Reload and scroll to top
[settingsTableView reloadData];
[settingsTableView setContentOffset:CGPointMake(0, 0) animated:NO];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [sectionArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"SettingsCell";
SettingsCellController *cell = (SettingsCellController *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"SettingsCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (SettingsCellController *) currentObject;
break;
}
}
}
// Set up the cell. Define values for Title and Description labels
[cell.titleLabel setText:[[sectionArray objectAtIndex:indexPath.row] valueForKey:@"Title"]];
// *****************************************************************************
// HERE'S WHERE THE PROBLEM OCCURS IN THE SECOND RUN, AFTER the value in then Detail View is updated
[cell.descriptionLabel setText:[[sectionArray objectAtIndex:indexPath.row] valueForKey:@"Description"]];
// ********************************************************************************
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (settingsDetailViewController == nil) {
settingsDetailViewController = [[SettingsDetailViewController alloc] initWithNibName:@"SettingsDetailView" bundle:nil];
}
settingsDetailViewController.navigationItem.title = [[sectionArray objectAtIndex:indexPath.row] valueForKey:@"Title"];
// Pass NSManagedObject reference to detailview
settingsDetailViewController.settingObject = [sectionArray objectAtIndex:indexPath.row];
BabymateAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.settingsNavigationController pushViewController:settingsDetailViewController animated:YES];
}
-(void)dealloc {
[settingsTableView release];
[settingsDetailViewController release];
[managedObjectContext release];
[sectionArray release];
[super dealloc];
}
@end
// SettingsDetailViewController.m
#import "SettingsDetailViewController.h"
#import "DataHelper.h"
@implementation SettingsDetailViewController
@synthesize settingsDetailTableView;
@synthesize managedObjectContext;
@synthesize settingArray;
@synthesize settingObject;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Some code, not relevant to the problem
// *****************************************************************************
// THIS SEEMS TO BE CAUSING THE PROBLEM
// Update current setting in database
[self.settingObject setValue:[tableView cellForRowAtIndexPath:indexPath].textLabel.text forKey:@"Description"];
// *****************************************************************************
// Commit
NSError *error;
if (![managedObjectContext save:&error]) NSLog([error domain]);
}