views:

154

answers:

4

I've got some (I think) pretty basic code for creating cell content from a data source, and everything works fine when the display loads. However, when I start scrolling around to view other text (up or down) the code fails with 'GDB: Program received signal: "EXEC_BAD_ACCESS"'. Here's the code that fills out the display for the various sections; each section has similar code:

id cell = (UITableViewCell *)[tableView
 dequeueReusableCellWithIdentifier:CellIdentifier
];

titledCell = [[[TitledCell alloc]
    initWithFrame:CGRectZero
  reuseIdentifier:CellIdentifier
 ] autorelease
];

switch (tableSection) {
  case TABLE_SECTION_1:
  if (cell == nil) {
   dataKey = @"a key from data source";
   dataFromSource = [viewData objectForKey:dataKey];

   titledCell.title.text = dataKey;
   titledCell.contents.text = dataFromSource;
   cell = titledCell;
   break;
  }
 case TABLE_SECTION_2:        
 ...
}
return cell;

As I was following the code, I noticed that the code skips the cell creation when scrolling the cell back into view, because cell != nil. If it skips, that means that cell contains the same contents as the first time it was created, right? Why is giving me trouble?

+1  A: 

I think the EXEC_BAD_ACCESS might caused by the:

titledCell.title.text = dataKey;

titledCell might get dealloced and when accessing the property there'll be a EXEC_BAD_ACCESS exception.

You can turn on the NSZombieEnabled env virable in: Group & Files -> Extutables -> Your App -> Get Info -> Arguments

al_lea
Sorry for the edit that made this answer irrelevant (I edited it as you posted your answer; I started investigating this possibility and discovered what the real problem was, so I updated the question with all the relevant code. Thanks for your help anyway! +1 because it was a "best guess" with the code I had posted!
JoBu1324
Actually, let me revise that: I don't understand the problem. It seams to me that the code should work because cell references the same memory space that titledCell does. The result should just empty the contents, right?
JoBu1324
I'd love to mark this as the answer. I'm pretty sure that the line you wrote down is indeed the line that was causing the crash - besides, I like Zombies :P Unfortunately, I can't do any testing to determine if it was correct, so I can only vote you up one.
JoBu1324
+1  A: 

Can't be 100% sure with the code sample you've given but a good guess would be the break statement is within the if block. So it should look like:

switch( tableSection ) {
    case TABLE_SECTION_1:
            if( cell == nil ) {
                    dataKey = @"a key from data source";
                    dataFromSource = [ viewData objectForKey:dataKey ];

                    titledCell.title.text = dataKey;
                    titledCell.contents.text = dataFromSource;
                    cell = titledCell;
            }
            break;
    case TABLE_SECTION_2:        
    ...
}
Argothian
A: 

I usually get EXEC_BAD_ACCESS when I forget to retain something. If you've got an autorelased object, it may work the first time through but not work the second time.

Run the program with debugging and use Xcode to figure out what line it's crashing on. That will be more helpful than anything else.

BJ Homer
This is generic enough that I know it's right, so you get the credit! I wish I had the original code to verify what was wrong with it though.
JoBu1324
A: 

Unfortunately, changes have made this question academic, so I can't really tell if any of the answers given are correct. The current code looks a little closer to this:

 id cell = (UITableViewCell *)[tableView
      dequeueReusableCellWithIdentifier:CellIdentifier
 ];

 if (cell == nil) {
      titledCell = [[[TitledCell alloc]
                   initWithFrame:CGRectZero
                 reuseIdentifier:CellIdentifier
           ] autorelease
      ];

      switch (tableSection) {
           case TABLE_SECTION_1:
                dataKey = @"a key from data source";
                dataFromSource = [viewData objectForKey:dataKey];

                titledCell.title.text = dataKey;
                titledCell.contents.text = dataFromSource;
                cell = titledCell;
                break;
           case TABLE_SECTION_2:
           ...
 }
 return cell;

...so that most of the code is now in the "if (cell == nil)" block (which makes more sense), and it works fine. I wish I understood what was wrong, but thanks for your Answers anyway!

JoBu1324
I've gotten much more familiar with Objective-C, so I know now that EXEC_BAD_ACCESS is indeed happens when you try to send a message to a deallocated object, so I am going to mark the best answer here as 'the' answer.
JoBu1324