Strange problem with cellForRowAtIndexPath:

Discussion in 'iOS Programming' started by RonC, Sep 19, 2011.

  1. RonC macrumors regular

    Joined:
    Oct 18, 2007
    Location:
    Chicago-area
    #1
    This one is a little weird - I can't seem to find anyone else who has had a similar problem so I'm coming here where answers abound!

    What I want to do is "blink" the selection status of a cell - toggle it between selected and deselected. I have the indexPath for this cell (for now, let's just call that (0,0), but it seems to fail independent of the value).

    Here's the code I'm using:
    Code:
    -(void)toggleRowSelection:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        if (cell) {
            NSLog(@"[%@] cell=%@ selected=%@", whoAmI(self, _cmd), cell, cell.isSelected);
            [cell setSelected:!cell.isSelected animated:YES];
        }
    }
            
    #define BLINK_ANIMATION_DELAY   (0.33)
    
    -(void)scanSuccessForAProw:(int)apRow
    {
        [self.tableView reloadData];
        // Animate the checkmark
        [self animateScanCheckmark:self.bigCheckmarkView
                         withSound:self.goodBeepSoundID];
        if (apRow >= 0) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:apRow
                                                        inSection:0];
            // Make sure row is visible
            [self.tableView selectRowAtIndexPath:indexPath
                                        animated:YES
                                  scrollPosition:UITableViewScrollPositionNone];
            
            NSLog(@"[%@] indexPath=%@ (%@ = %d)", whoAmI(self, _cmd),
                  indexPath, [self.tableView indexPathForSelectedRow],
                  [indexPath isEqual:[self.tableView indexPathForSelectedRow]]);
            // animate the row
    //        [self toggleRowSelection:indexPath];                    // ON
            [self performSelector:@selector(toggleRowSelection:)
                       withObject:indexPath
                       afterDelay:BLINK_ANIMATION_DELAY];           // OFF
            [self performSelector:@selector(toggleRowSelection:)
                       withObject:indexPath
                       afterDelay:2*BLINK_ANIMATION_DELAY];         // ON
            [self performSelector:@selector(toggleRowSelection:)
                       withObject:indexPath
                       afterDelay:3*BLINK_ANIMATION_DELAY];         // OFF
            [self animateTableView:TABLE_VIEW_ANIMATION_DURATION_SUCCESS];
        }
    }
    
    The code crashes at the NSLog statement in toggleRowSelection: with EXC_BAD_ACCESS. Apparently the value in cell is bad, so I started digging into that in the debugger. Here's my debugger log:
    Code:
    2011-09-19 13:38:03.713 Zone Installer[14360:207] [InventoryViewController_iPhone.scanSuccessForAProw:] indexPath=<NSIndexPath 0x5c555e0> 2 indexes [0, 0] (<NSIndexPath 0x5c555e0> 2 indexes [0, 0] = 1)
    Current language:  auto; currently objective-c++
    Single stepping until exit from function objc_msgSend, 
    which has no line number information.
    (gdb) p (int)[indexPath retainCount]
    $1 = 5
    (gdb) po tableView
    No symbol "tableView" in current context.
    (gdb) po [self tableView]
    <UITableView: 0x6849400; frame = (20 44; 280 223); clipsToBounds = YES; alpha = 0; autoresize = W+H; animations = { opacity=<CABasicAnimation: 0x5c644c0>; }; layer = <CALayer: 0x709d610>; contentOffset: {0, 0}>
    (gdb) po [[self tableView] cellForRowAtIndexPath:indexPath]
    <HaveNeedTableViewCell: 0x5c76720; baseClass = UITableViewCell; frame = (0 0; 280 44); autoresize = W; layer = <CALayer: 0x5c73740>>
    (gdb) p (int) [[[self tableView] cellForRowAtIndexPath:indexPath] retainCount]
    $2 = 2
    (gdb) po [[self tableView] visibleCells]
    <__NSArrayM 0x5c60660>(
    <HaveNeedTableViewCell: 0x5c76720; baseClass = UITableViewCell; frame = (0 0; 280 44); autoresize = W; layer = <CALayer: 0x5c73740>>,
    <HaveNeedTableViewCell: 0x5c79770; baseClass = UITableViewCell; frame = (0 44; 280 44); autoresize = W; layer = <CALayer: 0x5c799a0>>,
    <HaveNeedTableViewCell: 0x5c7ca00; baseClass = UITableViewCell; frame = (0 88; 280 44); autoresize = W; layer = <CALayer: 0x5c7cc30>>,
    <HaveNeedTableViewCell: 0x5c7fb50; baseClass = UITableViewCell; frame = (0 132; 280 44); autoresize = W; layer = <CALayer: 0x5c7fd80>>,
    <HaveNeedTableViewCell: 0x5c82c50; baseClass = UITableViewCell; frame = (0 176; 280 44); autoresize = W; layer = <CALayer: 0x5c82e80>>
    )
    
    (gdb) po [[self tableView] indexPathsForVisibleRows]
    <__NSArrayM 0x70c95a0>(
    <NSIndexPath 0x5c555e0> 2 indexes [0, 0],
    <NSIndexPath 0x5c78690> 2 indexes [0, 1],
    <NSIndexPath 0x5c7b910> 2 indexes [0, 2],
    <NSIndexPath 0x5c7ea60> 2 indexes [0, 3],
    <NSIndexPath 0x5c69c90> 2 indexes [0, 4]
    )
    
    (gdb) po indexPath
    <NSIndexPath 0x5c555e0> 2 indexes [0, 0]
    (gdb) p (int)[cell retainCount]
    $3 = 2
    gdb) po cell
    <HaveNeedTableViewCell: 0x5c76720; baseClass = UITableViewCell; frame = (0 0; 280 44); autoresize = W; layer = <CALayer: 0x5c73740>>
    (gdb) p (int)[cell isSelected]
    $4 = 96954113
    (gdb) 
    Any thoughts? Right now, I'm just going to turn off the selection blink animation, but it's frustrating me.

    Your help is appreciated!

    Ron C
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #2
    cell.isSelected must return a BOOL, which you can't print with %@. Try %d.
     

Share This Page