【问题标题】:Invalid update: invalid number of rows in section无效更新:节中的行数无效
【发布时间】:2015-07-01 01:46:26
【问题描述】:

我正在使用Microsoft Azure services 进行一个项目。在那删除一行时,我收到了这个错误:

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 中删除对象,然后再删除RowsAtIndexPaths。
  • 委托方法中的 fetchedResultsController 已经在这样做了。已经检查过了。
  • iBhavin 尝试过,但仍然出现相同的错误消息
  • 写入 [self.medicationTableView reloadData];在倒数第二行
  • 你可以参考THIS,和你一样的问题。

标签: ios xcode uitableview core-data azure-mobile-services


【解决方案1】:

- (void)swipeableTableViewCell: didTriggerRightUtilityButtonWithIndex:

你需要删除任何一个

[self.medicationsTableView reloadData]; 

[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];

因为在第一行调用reloadData 时,它会使用新数据源重新加载表格视图,并再次调用deleteRowsAtIndexPaths 尝试删除已通过调用reloadData 删除的行。

【讨论】:

    【解决方案2】:

    重要的是你需要使用任何一个

    [self.medicationsTableView reloadData];
    

    [self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
    

    原因是,当调用 tableview's reload data 时,从数据源中删除的行被删除,然后当为相同的 index path 调用删除行 api 时(该行已被删除会导致问题)

    同样在从表中删除行之前从数据源中删除对象 (self.fetchedResultsController1) 并调用

    [self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
    

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

    [self.medicationsTableView reloadData];
    

    【讨论】:

    • @TapasPal 没关系。两个答案之间存在一些差异。先检查一下
    • @TapasPal,一个人在创建答案时可能看不到他/她在创建答案过程中发布的答案,最重要的是他为什么要关心其他人发布他们的答案是否与我的相符或类似?
    • 在这种情况下,如果我们使用deleteRowsAtIndexPaths,则无需调用reloadData
    • @Tapas Pal,是的,你是绝对正确的,这也是我在回答中也提到的(见我回答的最后几行)
    • 大声笑@TapasPal 他偷了你的答案,甚至得到了比你更多的赞XD
    猜你喜欢
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 2013-07-28
    • 1970-01-01
    相关资源
    最近更新 更多