Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EXEC_BAD_ACCESS in UITableView cellForRowAtIndexPath

My UITableView is returning EXEC_BAD_ACCESS, but why!

See this code snippet!

Loading the UITableView works fine, so allXYZArray != nil and is populated!

Then scrolling the tableview to the bottom and back up causes it to crash, as it goes to reload the method cellForRowAtIndexPath

It fails on line:

    "NSLog(@"allXYZArray::count: %i", [allXYZArray count]);"

        (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAt

IndexPath:(NSIndexPath *)indexPath { 

static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];


cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
@try
{ 
if (allXYZArray == nil) {
   NSLog(@"nil");
   allXYZArray = [ToolBox getMergedSortedDictionaries:allXYZGiven SecondDictionary:allXYZSought];
}
NSLog(@"%i", [indexPath row]);
NSLog(@"allXYZArray::count: %i", [allXYZArray count]);
like image 934
David van Dugteren Avatar asked Apr 29 '10 02:04

David van Dugteren


2 Answers

EXC_BAD_ACCESS means that your program is trying to access a memory address that is invalid or otherwise inaccessible from your process. This most commonly happens when you try send a message to an object that has already been dealloced. So the first step in debugging EXC_BAD_ACCESS is to figure out which object your program was trying to send a message to when the crash happened. Often the answer isn't obvious, in which case, NSZombieEnabled is a great tool for identifying which line of code caused the crash.

In your case you've already determined that the crash happens when you call [allXYZArray count], making allXYZArray our prime suspect. This object is being returned from +[ToolBox getMergedSortedDictionaries:SecondDictionary:], so it's likely that your bug is in the implementation of that method. I would guess that it's returning an object that has already been released instead of autoreleased, as prescribed by the Memory Management Programming Guide for Cocoa. (This is one of the most important documents in the SDK, by the way. I recommend rereading it once a month until its policies and techniques become second nature.)

like image 136
cduhn Avatar answered Nov 19 '22 10:11

cduhn


Ok, reusing a cell, does not guarantee that the cell will be initialized properly:

UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:CellIdentifier];

cell will sometimes be null (especially the first time I guess).

Check cell for null and if so, initialize it properly.

if (cell == nil)
   cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
like image 43
Wim Haanstra Avatar answered Nov 19 '22 09:11

Wim Haanstra