dealloc on tableViewContoller causing crash when using popViewController on NavContr
Hi
I have a table view with a list of cells (which have sliders and labels in them, so not typical cells, but I think everything is released there when necessary, but I've always been a bit confused by tableViews: eg in this code, the list is short and I had trouble with it, so I gave all the cells custom identifiers so they wouldn't try to reuse them... Is that really bad? The list is only about 10 items long) and I replaced the default back button with a bar button system Cancel button and an alert that confirms you want to cancel and discard all changes. The cancel button links to a function which puts up the alert and then a delegate function calls the pop view controller on the navigation controller. It successfully goes back to the previous view, but then after a second it crashes. I added NSZombieEnabled and it showed me that the app was crashing on [super dealloc]; in the popped view controller's dealloc function. I would try to do it without using the pop, but the fact that this doesn't work probably means there is a bug in my memory management but I am not sure where.
The error said: Thread 1: Program received signal "EXC_BAD_ACCESS"
There seems to be a few people with similar issues, but no definitive answers that solve the problem.
The push onto the navigation controller stack from the first view controller
Code:
-(IBAction) beginNewTest {
NSLog(@"Beginning new test. FirstViewController.m");
TestListViewController* testListViewController = [[TestListViewController alloc] init];
testListViewController.title = @"New Test";
[self.navigationController pushViewController:testListViewController animated:YES];
[testListViewController release];
NSLog(@"Complete initialization and loading of test list view controller. Pushed onto navigation stack. FirstViewController.m");
}
//the init function in the TestListViewController
-(id) init {
if (self = [super initWithStyle: UITableViewStylePlain]) {
//initialize here
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelTest)]; //make it cancel
[self.navigationItem setHidesBackButton:TRUE];
[self.navigationItem setLeftBarButtonItem:cancelButton];
[cancelButton release];
}
return self;
}
//The problem occurs with or without the alertview, so that's not causing it...
-(void) cancelTest {
NSLog(@"Cancelling test TestListViewController.m");
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Canceling Test" message:@"Are you sure you want to cancel the test? All unsaved data will be lost." delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
[alert show];
[alert release];
}
-(void) alertView: (UIAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex {
if (buttonIndex == 1)
[self.navigationController popViewControllerAnimated:YES];
else
return;
}
//Here's the dealloc
- (void)dealloc {
NSLog(@"Dealloc function reached. TestListViewController.m");
[scoreForTest release]; //an ns dictionary allocated in viewdidload
[super dealloc]; //crashes here acc. to NSZombieEnabled
}
Any ideas?
Thanks!
Last edited by shimmy; 07-03-2011 at 12:14 PM.
Reason: used code tags
I love it when people show everything except what is important. Like this:
Code:
[scoreForTest release]; //an ns dictionary allocated in viewdidload
So, perhaps you should show that.
Code:
- (void)viewDidLoad {
[super viewDidLoad];
startDateTime = [NSDate date]; //get start time, and will compare with end time to determine time to score. May want to only set this after first score has been altered
if (scoreForTest == nil) {
//dictionary with integer values for scores (initialized to -1 so no ambiguity)
NSArray* arrayOfScores = [NSArray arrayWithObjects:[NSNumber numberWithInt:-1], [NSNumber numberWithInt:-1], [NSNumber numberWithInt:-1],
[NSNumber numberWithInt:-1], [NSNumber numberWithInt:-1], [NSNumber numberWithInt:-1],
[NSNumber numberWithInt:-1], [NSNumber numberWithInt:-1], [NSNumber numberWithInt:-1],
[NSNumber numberWithInt:-1], nil];
scoreForTest = [[NSMutableDictionary alloc] initWithObjects:arrayOfScores forKeys:self.arrayOfTestTitles];
}
self.editing = NO;
UIButton* infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:self action:@selector(requestHelp:) forControlEvents:UIControlEventTouchUpInside];
[infoButton setFrame:CGRectMake(10, 0, 20, 20)];
UIBarButtonItem *infoBarButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
self.navigationItem.rightBarButtonItem = infoBarButton;
[infoButton release];
}
infoButton should not be released, and I suggest you read the properties link in my signature.
Why shouldn't it be released?
EDIT: Oh sorry. It should be releasing inforBarButton, not infoButton.
EDIT 2: Reading through your properties guide -- very informative! Do you think this is causing my problems?
EDIT 3: The changes I made (releasing infoBarButton instead of infoButton and also modifying the allocation of score for test based on your guide) has fixed the problem! Thank you very much! I was always very confused by the memory management, especially with properties, and your guide has helped clear a lot of that up already. I suggest everyone take a look at it.
Last edited by shimmy; 07-03-2011 at 12:13 PM.
Reason: added more detail , changes in status