I'm facing some sort of memory related issue I cannot figure out.
I have one summary view that lists some settings and a detail view where you can edit each setting.
In the summary view I have a tableview populated by an array (settingArray) of settings which in turn is loaded from a core data repository.
// SettingsViewController.h
@interface SettingsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *settingArray;
}
@property (nonatomic, retain) NSMutableArray *settingArray;
// SettingsViewController.m
- (void)viewWillAppear:(BOOL)animated {
[self setSettingArray:[DataHelper searchObjectsInContext:@"Sections" :nil :@"Id" :YES :managedObjectContext]];
}
This array of NSManaged objects is used to assign values to a custom UITableViewCell which has two labels: title and description.
// SettingsViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[…]
[cell.titleLabel setText:[[settingArray objectAtIndex:indexPath.row] valueForKey:@"Title"]];
[cell.descriptionLabel setText:[[settingArray objectAtIndex:indexPath.row] valueForKey:@"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.
// SettingsViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (settingsDetailViewController == nil) {
settingsDetailViewController = [[SettingsDetailViewController alloc] initWithNibName:@"SettingsDetailView" bundle:nil];
}
// Pass corresponding settingArray object to detail view in the settingObject variable
settingsDetailViewController.settingObject = [settingArray objectAtIndex:indexPath.row];
[…]
}
In the detail view, the user can modify some values and then save the modified core data object in the database.
// SettingsDetailViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Update current setting in database
[self.settingObject setValue:[tableView cellForRowAtIndexPath:indexPath].textLabel.text forKey:@"Description"];
}
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 settingArray.
// SettingsViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[cell.titleLabel setText:[[settingArray objectAtIndex:indexPath.row] valueForKey:@"Title"]];
// HERE IS WHERE THE ERROR OCCURS IN THE SECOND PASS
[cell.descriptionLabel setText:[[settingArray objectAtIndex:indexPath.row] valueForKey:@"Description"]];
[…]
}
I guess it's related to the release of the settingArray or settingObject being used, but I tried different approaches and no solution yet. All variables are declared in the corresponding .h, properties are added using nontoxic and retain, the accessors are synthesized in the .m and the objects are released in the dealloc function. According to the Cocoa memory management guidelines it should work.
The funny thing is that other parts of my code use identical arrays and pass identical objects with no problems whatsoever.
Any hints please?