views:

879

answers:

3

I have a TableView that builds and draws ok, but then crashes on scrolling the view. I've run through the debugger and it appears that my class level variables are being overwritten somehow so they no longer exist when the titleForHeaderInSection is being called again. The very strange thing is that if I replace the code:

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *sectionTitle = [favouritesDataSections objectAtIndex:section];
return sectionTitle;
}

with:

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *sectionTitle = @"Test";
return sectionTitle;
}

It still crashes but this time the debugger lists not an NSString when you hover over the sectionTitle variable.

This is the code I used to create the view and set up the class level variables:

- (void)loadView {
[super loadView];
CGRect tableSize = CGRectMake(0,0,320,460);
UITableView *favouritesTableView = [[UITableView alloc] initWithFrame:tableSize style:UITableViewStylePlain];
favouritesTableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
favouritesTableView.dataSource = self;
favouritesTableView.delegate = self;
favouritesTableView.rowHeight = 52;
[self.view addSubview:favouritesTableView];
}

- (void)viewDidLoad {
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Get the full path of the favourites plist
NSString *filename = [documentsDirectory stringByAppendingPathComponent:@"Favourites.plist"];
// Initialise Dictionary and array
favouritesDataAll = [[NSMutableDictionary alloc] init];
favouritesDataSections = [[NSArray alloc] init];

NSDictionary *dict = [[[NSMutableDictionary alloc] initWithContentsOfFile:filename] retain];
favouritesDataAll = dict;
[dict release];

favouritesDataSections = [favouritesDataAll allKeys]; 
}

I am going absolutely mad trying to track this down - spent 2 days on it so far so would be externally grateful for any help.

Best regards

Dave

A: 

Sounds like there's some sort of memory corruption going on here.

One thing I see is that those calls to [super ...] should occur after the other code in those methods.

What happens if you adjust your tableview to only have one section?

Greg
Hi Greg, Thanks for the quick reply. Unfortunately, putting the super at the end causes it to crash (i.e., the TableView doesn't even get drawn). I also tried setting the section count manually to 1, the number of rows in section to 1 and the section title to @"Test". Still crashes on the scroll.
Magic Bullet Dave
+2  A: 

OK, fixed it... changed

favouritesDataSections = [favouritesDataAll allKeys];

To:

favouritesDataSections = [[favouritesDataAll allKeys] retain];

And it all appears to work. From this I would deduce that the array I was using to store the section headings was pointing to data that was autoreleased at some random point, which is why it was barfing at seemingly odd places.

I do admit though that I am still at the "trial and error" stage of coding and don't fully understand what I am doing (I am sure you will be cringing reading this). It would be useful to me if you have any thoughts/comments links to further reading or posts about how all this is working (i.e., when and why to use retain, etc) to further my understanding.

Thanks again, Dave

Magic Bullet Dave
Dave, go and read the memory management rules in Apple's documentation. This is an elementary mistake which you wouldn't have made if you'd done a bit of reading first.
NSResponder
+1  A: 

I would recommend using the @property setters to avoid this problem, the array is autoreleased, so you called a manual retain on it, this fixed the problem, but a simpler fix would be to use:

self.favoritesDataSection

This is automated by @property (retain) retain means retain is called when this is set, and release when it is set to nil or a different object.

Alex Gosselin