0

基本上,我正在尝试编写一个应用程序,它的 tableview 包含两个部分,一个包含未完成的任务(单元格),另一个包含已完成的任务。每个单元格都有一个复选框 UIButton 子类。问题是当我检查超过一半的项目时,它会因 NSRangeException 而崩溃。我真的很感激关于这个问题的任何建议。

错误:* 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“* -[__NSArrayM objectAtIndex:]:索引 9 超出范围 [0 .. 8]”

CheckMarkTapped 方法(调用以切换项目):

-(void)checkMarkTapped:(UIButton *)sender {

    UITableViewCell *cell = ((UITableViewCell *)[sender superview]);
    NSIndexPath *originIndexPath = [self.tableView indexPathForCell:cell];
    NSIndexPath *destinationIndexPath;

    NSLog(@"originIndexPath row: %i, section: %i", originIndexPath.row, originIndexPath.section);

    [self fixAllCheckboxes];

    if (originIndexPath.section == 0) {

        destinationIndexPath = [NSIndexPath indexPathForRow:[completedItems count] inSection:1];
        [sender setSelected:NO];

        NSMutableDictionary *tempDict = [[NSDictionary dictionaryWithDictionary:[uncompletedItems objectAtIndex:originIndexPath.row]]mutableCopy];
        [completedItems addObject:tempDict];
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:destinationIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
        [uncompletedItems removeObjectAtIndex:originIndexPath.row];


    }

    if (originIndexPath.section == 1) { //if the checkbox is in section 1
        [sender setSelected:YES];

        NSMutableDictionary *tempDict = [NSDictionary dictionaryWithDictionary:[[completedItems objectAtIndex:originIndexPath.row]mutableCopy]];

        destinationIndexPath = [NSIndexPath indexPathForRow:[[tempDict objectForKey:@"index"]intValue] inSection:0];
        [uncompletedItems insertObject:tempDict atIndex:[[tempDict objectForKey:@"index"]intValue]];
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:destinationIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
        [completedItems removeObjectAtIndex:[self.tableView indexPathForCell:cell].row];

    }

    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:originIndexPath, nil] withRowAnimation:UITableViewRowAnimationLeft];
}

CELLFORROWATINDEXPATH 方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    if (indexPath.section == 1) {
        CellIdentifier = @"Cell1";
    }

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.showsReorderControl = YES;
    }

    for (UIControl *checkbox in [cell subviews]) {
        if (checkbox.tag == 9001) {
            [checkbox removeFromSuperview];
        }
    }

    if (indexPath.section == 0) {
        UIButton *checkbox = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
        [checkbox addTarget:self action:@selector(checkMarkTapped:) forControlEvents:UIControlEventTouchUpInside];
        [cell setIndentationWidth:45];
        [cell setIndentationLevel:1];

        [checkbox setTag:9001];
        [checkbox setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
        [checkbox setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateSelected];

        [cell addSubview:checkbox];

        cell.textLabel.backgroundColor = [UIColor whiteColor];
        cell.textLabel.backgroundColor = [UIColor whiteColor];
        cell.contentView.backgroundColor = [UIColor whiteColor];
        cell.textLabel.font = [UIFont boldSystemFontOfSize:20];

        switch (indexPath.section) {
            case 0:
                cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
                break;
            case 1:
                cell.textLabel.text = [[completedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
                [checkbox setSelected:YES];
                break;
            default:
                break;
        }

        [cell addSubview:checkbox];

    } else if (indexPath.section == 1) {

        UIButton *checkbox = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
        [checkbox addTarget:self action:@selector(checkMarkTapped:) forControlEvents:UIControlEventTouchUpInside];
        [cell setIndentationWidth:45];
        [cell setIndentationLevel:1];
        [checkbox setTag:9001];

        cell.textLabel.backgroundColor = [UIColor whiteColor];
        cell.textLabel.backgroundColor = [UIColor whiteColor];
        cell.contentView.backgroundColor = [UIColor whiteColor];
        cell.textLabel.font = [UIFont boldSystemFontOfSize:20];
        cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];

        [checkbox setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
        [checkbox setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateSelected];

        [cell addSubview:checkbox];

        switch (indexPath.section) {
            case 0:
                cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
                break;
            case 1:
                cell.textLabel.text = [[completedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
                [checkbox setSelected:YES];
                break;
            default:
                break;
        }

        [cell addSubview:checkbox];
    }
    return cell;
}

这是崩溃的 NSLog。如您所见,当数组具有相等数量的项目时会发生这种情况:

2012-12-26 12:54:44.583 Checklist R4[1128:c07] Destination Row: 0, UnCompleted Count: 19, Completed Count: 1
2012-12-26 12:54:45.034 Checklist R4[1128:c07] Destination Row: 1, UnCompleted Count: 18, Completed Count: 2
2012-12-26 12:54:45.454 Checklist R4[1128:c07] Destination Row: 2, UnCompleted Count: 17, Completed Count: 3
2012-12-26 12:54:45.873 Checklist R4[1128:c07] Destination Row: 3, UnCompleted Count: 16, Completed Count: 4
2012-12-26 12:54:46.294 Checklist R4[1128:c07] Destination Row: 4, UnCompleted Count: 15, Completed Count: 5
2012-12-26 12:54:47.072 Checklist R4[1128:c07] Destination Row: 5, UnCompleted Count: 14, Completed Count: 6
2012-12-26 12:54:47.399 Checklist R4[1128:c07] Destination Row: 6, UnCompleted Count: 13, Completed Count: 7
2012-12-26 12:54:48.085 Checklist R4[1128:c07] Destination Row: 7, UnCompleted Count: 12, Completed Count: 8
2012-12-26 12:54:48.621 Checklist R4[1128:c07] Destination Row: 8, UnCompleted Count: 11, Completed Count: 9
2012-12-26 12:54:49.090 Checklist R4[1128:c07] Destination Row: 9, UnCompleted Count: 10, Completed Count: 10
2012-12-26 12:54:50.234 Checklist R4[1128:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 9 beyond bounds [0 .. 8]'
4

2 回答 2

2

您的completedItemsuncompletedItems数组,其中一个只有 8 个项目,但您试图访问的项目不止于此。检查你的numberOfRowsInSection方法,给出它们的动态值,比如

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int rowCount = 0;
    if (section == 0) {
        rowCount = [uncompletedItems count];
    } else {
        rowCount = [completedItems count];
    }
    return rowCount;
}

而且它不需要两者switch和。使用if任何人来检查你section是 0 还是 1。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

if (indexPath.section == 1) {
    CellIdentifier = @"Cell1";
}

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    cell.showsReorderControl = YES;
}

for (UIControl *checkbox in [cell subviews]) {
    if (checkbox.tag == 9001) {
        [checkbox removeFromSuperview];
    }
}

    UIButton *checkbox = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];
    [checkbox addTarget:self action:@selector(checkMarkTapped:) forControlEvents:UIControlEventTouchUpInside];
    [cell setIndentationWidth:45];
    [cell setIndentationLevel:1];

    [checkbox setTag:9001];
    [checkbox setImage:[UIImage imageNamed:@"unchecked"] forState:UIControlStateNormal];
    [checkbox setImage:[UIImage imageNamed:@"checked"] forState:UIControlStateSelected];

    [cell addSubview:checkbox];

    cell.textLabel.backgroundColor = [UIColor whiteColor];
    cell.textLabel.backgroundColor = [UIColor whiteColor];
    cell.contentView.backgroundColor = [UIColor whiteColor];
    cell.textLabel.font = [UIFont boldSystemFontOfSize:20];

    switch (indexPath.section) {
        case 0:
            cell.textLabel.text = [[uncompletedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
            break;
        case 1:
            cell.textLabel.text = [[completedItems objectAtIndex:indexPath.row]objectForKey:@"Name"];
            [checkbox setSelected:YES];
            break;
        default:
            break;
    }

    [cell addSubview:checkbox];

return cell;
}
于 2012-12-26T03:39:03.243 回答
0

您的代码中可能存在两个问题

  1. You are returning numbers of rows to Table View less then your array count.
  2. Your array is exceeding from the numbers of rows in Table View.

您的描述error清楚地表明您的数组有8索引,但您正在访问9th导致错误的索引。

于 2012-12-26T04:42:15.913 回答