web-dev-qa-db-ja.com

無効な更新:セクションの行数が無効です

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;
}

どこがいけないのか教えてください。よろしくお願いします!!!!

7
user1722889

- (void)swipeableTableViewCell: didTriggerRightUtilityButtonWithIndex:

どちらかを削除する必要があります

[self.medicationsTableView reloadData]; 

または

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

最初の行でreloadDataが呼び出されると、テーブルビューが新しいデータソースでリロードされ、再度deleteRowsAtIndexPathsを呼び出すと、以前にreloadDataを呼び出して削除した行が削除されます。

17
Tapas Pal

重要なことは、どちらかを使用する必要があるということです

[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];
11
Sanjay Mohnani