无缘无故从获取的结果中删除托管对象

Posted

技术标签:

【中文标题】无缘无故从获取的结果中删除托管对象【英文标题】:Managed Object Removed from Fetched Results For No Reason 【发布时间】:2012-10-22 00:33:33 【问题描述】:

我有一个奇怪的问题,我想不通。我有一个相当典型的UIViewController 和一个UITableView 和一个NSFetchedResultsController 从SQLite 存储中获取对象。提取工作正常,表格工作正常,典型的 NSFetchedResultsController 样板:

-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller

    [self.tableView beginUpdates];

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

    if(type==NSFetchedResultsChangeInsert)
        [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
     else if(type==NSFetchedResultsChangeDelete)
        [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
    


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

    UITableView *tV = self.tableView;
    if(type==NSFetchedResultsChangeInsert)
        [tV insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
     else if(type==NSFetchedResultsChangeDelete)
        [tV deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
     else if(type==NSFetchedResultsChangeUpdate)
        [self configureCell:[tV cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
     else if(type==NSFetchedResultsChangeMove)
        [tV deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [tV insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
    


-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    [self.tableView endUpdates];

我遇到的问题是任何关系为 nil 的对象(即使关系属性不涉及谓词或排序描述符中的获取请求)从获取的结果中消失(controller:didChangeObject: 被调用与NSFetchedResultsChangeDelete) 一起以任何方式更新它们(例如更改不相关的属性)。如果我重新执行提取,对象将返回。

即使我在获取请求中不使用谓词也会发生这种情况。

有人知道这里发生了什么吗?

【问题讨论】:

总有一个原因,没有什么比代码叛逆=D 您应该添加对您的实体/属性/关系的描述,并显示您如何创建获取的结果控制器的代码。 【参考方案1】:

我可以通过更改 NSFetchedResultsController 上的 sectionNameKeyPath 来解决此问题。如果您的 sectionNameKeyPath 属性是可选的关系属性,请尝试将其删除或更改。

如果您实际上想使用该属性来分隔各个部分,则可能需要使用“虚拟”对象来表示 nil。 (这实际上意味着如果您将其用于您的部分,则该属性不能是可选的。)

【讨论】:

在您了解问题所在之前,这不是真正的解决方案。 问题在于 NSFetchedResultsController 上的 sectionNameKeyPath 是可选的(因此对于某些对象来说是 nil。)这可能不是一个解决方案,但它至少是对问题的一个解释。

以上是关于无缘无故从获取的结果中删除托管对象的主要内容,如果未能解决你的问题,请参考以下文章

Core Data - 批量处理获取结果的属性

从托管对象上下文中删除后使用保留的 NSManagedObject 是不是安全?

使用托管对象中的集合作为获取结果控制器的数据

区分从内存中托管对象上下文和持久存储中获取的对象

从C#中的托管对象属性获取值的最佳方法

Core Data,我如何有效地查找和删除托管对象