如何从数据数组中删除对象(核心数据)

Posted

技术标签:

【中文标题】如何从数据数组中删除对象(核心数据)【英文标题】:How to remove an object from data array (core data) 【发布时间】:2014-05-21 13:29:02 【问题描述】:

我有一个带有部分的表格视图。当我尝试从表视图中删除一行时,出现以下错误............

'无效更新:第 5 节中的行数无效。更新后现有节中包含的行数 (4) 必须等于更新前该节中包含的行数 (4 ),加上或减去从该节插入或删除的行数(0 插入,1 删除),加上或减去移入或移出该节的行数(0 移入,0 移出)。' em>

经过一些在线研究,我了解到我必须从数组中删除对象。 我正在使用标准 managedObjectContext 和 fetchedResultsController 的核心数据。我不明白这里的数组是什么。 有人可以帮忙吗。

这里是节数和行数的代码......

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    NSInteger count = [[self.fetchedResultsController sections] count];
    return count;



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];

    NSInteger count = [sectionInfo numberOfObjects];
    return count;

下面是我用来删除一行的代码......

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    if (editingStyle == UITableViewCellEditingStyleDelete) 

        // Delete the managed object at the given index path.
        NSManagedObject *birthdayToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
        [self.managedObjectContext deleteObject:birthdayToDelete];

        // Update the array and table view.
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:YES];

        // Commit the change.
        NSError *error = nil;
        if (![self.managedObjectContext save:&error]) 
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        
    

    [_birthdayTableView reloadData];

【问题讨论】:

你能展示你的numberOfRowsInSection实现吗? 感谢您的回复。我用更多代码更新了我的问题。 我对 NSFetchResultsController 不是很熟悉,但我想说你应该刷新 self.fetchedResultsController 或再次执行请求。首先你是如何创建它的? 【参考方案1】:

如果您使用的是NSFetchResultsController 委托方法,则无需调用[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:YES];。执行以下操作:在您保存 managedObjectContext 删除后,这些将被调用。 (记得设置你的NSFetchedResultsController 的代表。另外,不要调用[tableView reloadData];。它会使动画跳过并且看起来很奇怪:-) 这就是使用NSFetchedResultsController 的美妙之处,它为你做了繁重的工作监听managedObjectContext上的变化

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

    [tableView beginUpdates];


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type

       switch(type) 
         case NSFetchedResultsChangeInsert:
             [tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                      withRowAnimation:UITableViewRowAnimationRight];
        break;

        case NSFetchedResultsChangeDelete:
             [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                      withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case NSFetchedResultsChangeMove:break;
        case NSFetchedResultsChangeUpdate:break;
    


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath

     switch(type) 

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
            break;

        case NSFetchedResultsChangeUpdate:
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
            break;
    



- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

     [tableView endUpdates];

【讨论】:

设法为更新设置动画。刚刚将 UITableViewRowAnimationNone 更改为 UITableViewRowAnimationFade。 就是这个。您可以使用几种不同的动画。【参考方案2】:

这通常是由于您的数组中的项目数与从numberOfRowsInSection: 返回的数字不一致造成的

【讨论】:

这就是我要问的问题,如何更新数组(或从数组中删除对象)

以上是关于如何从数据数组中删除对象(核心数据)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 3 中从核心数据中删除对象

SWIFT 的核心数据:如何从关系实体中删除对象?

核心数据:如何删除不在新数据中的对象

如何将选定的 uitableviewcell 核心数据对象传递给新的视图控制器?

如何将获取的对象保存到核心数据

如何从 javascript 变量中删除对象/数组?