无效更新:部分中行数无效

7

我正在使用 Microsoft Azure 服务 进行项目开发。在删除一行时,遇到了以下错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (2) must be equal to the number of rows 
contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).
加载和删除行的代码如下:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    //medicine list
    if (section == 0) {
        NSArray *sectionInfo = [self.fetchedResultsController1 fetchedObjects];
        return [sectionInfo count];

    }
    //allergy list
    else if (section == 1) {
        NSArray *sectionInfo = [self.fetchedResultsController2 fetchedObjects];
        return [sectionInfo count];

    }
    //notes list
    else if (section == 2){
        NSArray *sectionInfo = [self.fetchedResultsController3 fetchedObjects];
        return [sectionInfo count];
    }
    else
        return 0;
 }

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

    static NSString *cellIdentifier = @"mcell";
    MedicationTableViewCell *cell = (MedicationTableViewCell *)    [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    //  Add utility buttons 
    NSMutableArray *rightUtilityButtons = [NSMutableArray new];
    [rightUtilityButtons sw_addUtilityButtonWithColor: [UIColor colorWithRed:1.0f green:0.231f blue:0.188 alpha:1.0f] title:@"Delete"];

    switch (indexPath.section) {
        case 0: {
            NSManagedObject *item = [self.fetchedResultsController1 objectAtIndexPath:indexPath];
            cell.textLabel.text = [item valueForKey:@"name"];
            break;
        }
        case 1: {
            NSManagedObject *item = [self.fetchedResultsController2 objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]];
            cell.textLabel.text = [item valueForKey:@"name"];
            break;
        }
        case 2: {
            NSManagedObject *item = [self.fetchedResultsController3 objectAtIndexPath: [NSIndexPath indexPathForRow:indexPath.row inSection:0]];
            cell.textLabel.text = [item valueForKey:@"title"];
            break;
        }
        default:
            break;
    }
    cell.rightUtilityButtons = rightUtilityButtons;
    cell.delegate = self;

    return cell;
}

- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index {

 // Delete button is pressed
 NSIndexPath *cellIndexPath = [self.medicationsTableView indexPathForCell:cell];

 //fetchingg data from local store first
 NSManagedObject *item = [self.fetchedResultsController1 objectAtIndexPath:[NSIndexPath indexPathForRow:cellIndexPath.row inSection:0]];

   NSMutableArray *keys = [[NSMutableArray alloc] initWithObjects:@"id", @"name", @"userId", nil];
   NSMutableArray *values = [[NSMutableArray alloc] initWithObjects: [item valueForKey:@"id"], [item valueForKey:@"name"], [item valueForKey:@"userId"], nil];

    //creating dictionary of data
    NSDictionary *dict = [[NSDictionary alloc] initWithObjects:values forKeys:keys];

    //calling delete fucntion
    [self.authService deleteItem:self.syncTable withDict:dict completion:^{
    //removing row from table view
    [self.medicationsTableView reloadData];
    [self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
      }];
      break;
}

请告诉我我哪里出错了。先谢谢!!!

在你删除行之前,你需要从self.fetchedResultsController1中移除对象。 - iBhavin
委托方法中的fetchedResultsController已经在执行此操作。已经检查过了。 - user1722889
iBhavin尝试过了,但仍然出现相同的错误信息。 - user1722889
在倒数第二行写入 [self.medicationTableView reloadData]; - Ashok Londhe
1
你可以参考这个链接,和你遇到的问题一样。 - Viral Savaj
首先,从您的数据源中删除对象,即self.fetchedResultsController1,然后使用以下代码删除行: [self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];重新加载tableview是不必要的。 - Vinaykrishnan
2个回答

17
- (void)swipeableTableViewCell: didTriggerRightUtilityButtonWithIndex: 中,您需要移除其中一个

标签。
[self.medicationsTableView reloadData]; 
或者
[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];

因为在第一行调用 reloadData 时,它使用新的数据源重新加载了tableview,并且再次调用deleteRowsAtIndexPaths 尝试删除之前已经通过调用reloadData 删除的行。


11
重要的是你需要使用以下两种之一:

[self.medicationsTableView reloadData];
或者
[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
原因是,当调用tableview的reload data时,从数据源中删除的行将被删除,之后再为同一索引路径(已删除行所在的位置)调用删除行API会导致问题。 此外,在从表中删除行之前,从数据源(self.fetchedResultsController1)中删除对象并调用。
[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];

在上一行的删除动画完成后,您可以调用(但不是必需的)。

[self.medicationsTableView reloadData];

3
没问题,@TapasPal。两个答案之间有一些差别,请先进行核实。 - Ashok Londhe
3
@TapasPal,有时候一个人在回答问题的过程中可能没有看到其他人已经发表的回答,而且更重要的是,为什么他要关心其他人的帖子,无论他们的答案是否与我的相符或者类似? - Sanjay Mohnani
在这种情况下,如果我们使用 deleteRowsAtIndexPaths,就不需要调用 reloadData - Tapas Pal
@Tapas Pal,是的,你说得完全正确,这也是我在我的答案中提到的(请参见我的答案的最后几行)。 - Sanjay Mohnani
1
哈哈,@TapasPal,他抄袭了你的答案,甚至还得到了比你更多的赞 XD - Josh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接