Search code examples
iosobjective-cnsrangeexception

App crashing when table cell expanded


I have a system in place to add a cell to a section when the already existing cell is pressed. The app crashes when I try to expand any section after and including indexpath 3. It generates the following crash report:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 4 beyond bounds [0 .. 2]'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000101983495 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001016e299e objc_exception_throw + 43
    2   CoreFoundation                      0x000000010193be3f -[__NSArrayI objectAtIndex:] + 175
    3   Quick Fit                           0x00000001000123d6 -[tuesdayVC tableView:cellForRowAtIndexPath:] + 1878
    4   UIKit                               0x0000000100363f8a -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 348
    5   UIKit                               0x000000010054d5ed -[_UITableViewUpdateSupport(Private) _setupAnimationsForNewlyInsertedCells] + 7364
    6   UIKit                               0x0000000100556a81 -[_UITableViewUpdateSupport _setupAnimations] + 193
    7   UIKit                               0x000000010034c615 -[UITableView _updateWithItems:updateSupport:] + 1639
    8   UIKit                               0x0000000100348000 -[UITableView _endCellAnimationsWithContext:] + 11615
    9   Quick Fit                           0x0000000100012c3f -[tuesdayVC tableView:didSelectRowAtIndexPath:] + 879
    10  UIKit                               0x00000001003575c2 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1312
    11  UIKit                               0x00000001003576eb -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 221
    12  UIKit                               0x00000001002a8100 _applyBlockToCFArrayCopiedToStack + 316
    13  UIKit                               0x00000001002a7f71 _afterCACommitHandler + 460
    14  CoreFoundation                      0x000000010194edc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    15  CoreFoundation                      0x000000010194ed37 __CFRunLoopDoObservers + 391
    16  CoreFoundation                      0x000000010192e522 __CFRunLoopRun + 946
    17  CoreFoundation                      0x000000010192dd83 CFRunLoopRunSpecific + 467
    18  GraphicsServices                    0x0000000103af9f04 GSEventRunModal + 161
    19  UIKit                               0x000000010028fe33 UIApplicationMain + 1010
    20  Quick Fit                           0x00000001000153d3 main + 115
    21  libdyld.dylib                       0x000000010201b5fd start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

From looking over the crash report, I think this method is broken:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self tableView:tableView canCollapseSection:indexPath.section])
    {
        if (!indexPath.row)
        {
            // only first row toggles exapand/collapse
            [tableView deselectRowAtIndexPath:indexPath animated:YES];

            NSInteger section = indexPath.section;
            BOOL currentlyExpanded = [expandedSections containsIndex:section];
            NSInteger rows;

            NSMutableArray *tmpArray = [NSMutableArray array];

            if (currentlyExpanded)
            {
                rows = [self tableView:tableView numberOfRowsInSection:section];
                [expandedSections removeIndex:section];

            }
            else
            {
                [expandedSections addIndex:section];
                rows = [self tableView:tableView numberOfRowsInSection:section];
            }

            for (int i=1; i<rows; i++)
            {
                NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i
                                                               inSection:section];
                [tmpArray addObject:tmpIndexPath];
            }

            UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

            if (currentlyExpanded)
            {
                [tableView deleteRowsAtIndexPaths:tmpArray
                                 withRowAnimation:UITableViewRowAnimationTop];

                cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor orangeColor] type:DTCustomColoredAccessoryTypeDown];

            }
            else
            {
                [tableView insertRowsAtIndexPaths:tmpArray
                                 withRowAnimation:UITableViewRowAnimationTop];
                cell.accessoryView =  [DTCustomColoredAccessory accessoryWithColor:[UIColor orangeColor] type:DTCustomColoredAccessoryTypeUp];

            }
        }
    }
}

Solution

  • Try tho, it turn out to be that there isn't enough data in your array collected by the table view when called. Try this: and place it within your view did load.

    self.techniques = [[NSArray alloc] initWithObjects:@"-",
                       @"-",
                       @"-",
                       @"-",
                       @"-", nil];