从核心数据中删除对象并切换视图控制器时崩溃
Crash when deleting object from Core Data and toggling view controllers
我正在初始屏幕上为 NSManaged 对象创建 NSFetchRequest。我有时会在以下情况下崩溃:
- 切换到我的标签栏控制器中的另一个视图控制器
- 使用相同的托管对象类型发出另一个获取请求
- 删除一个常见的托管对象,它也出现在我最初的 VC 的 fetchrequest 中。 VC 包含一个 table 视图。
- 保存托管上下文
- 切换到第一个 VC,然后重新加载数据
我没有使用 NSFetchResutltsController 来管理这些 returned 对象。当我的 table 视图重新加载时发生崩溃。我确实提出了另一个请求,并希望删除的对象不会被 returned,但确实如此。当我的单元格试图读取已删除对象的 属性 时,它读取 uninitialized
并崩溃。在 2 VC 之间切换时,大约有五分之一会发生这种情况。我在所有 CoreData 函数中都使用了 performAndWait
。
有没有办法解耦两个屏幕之间Managed Objects的关系?如果没有,我如何才能在第一个 VC 中获取我的提取请求,而不是 return 在第二个 VC 中删除的对象,让它们保持同步?
NSManagedObject 不同于其他对象。它本身不包含任何信息。它有一个指向其上下文的指针和一个 objectID。当您访问它的属性时,它会将请求转发到上下文以获取所需的信息。因此,当从上下文中删除实体时,managedObject 停止工作并导致崩溃。这就是为什么总的来说,我认为永远保留指向 managedObject 的指针并始终使用 fetchedResultsController 访问它们是一种不好的做法,即使仅针对一个对象,并且仅在 managedObjects 结果随后被丢弃时才进行提取。
您在问题中暗示了两种可能的解决方案。您可以从 managedObject 中复制值,也可以使用 fetchedResultsController。如果您复制这些值,那么即使在实体被删除后它也会正常显示。如果您使用 fetchedResultsController,那么 fetchedObjects 属性 将永远不会包含已删除的对象,并且该对象在删除后将无法访问。
我建议使用 fetchedResultsController。你不需要害怕它。这不是一个很大的开销,即使您只获取一个对象也可以合理使用。
我正在初始屏幕上为 NSManaged 对象创建 NSFetchRequest。我有时会在以下情况下崩溃:
- 切换到我的标签栏控制器中的另一个视图控制器
- 使用相同的托管对象类型发出另一个获取请求
- 删除一个常见的托管对象,它也出现在我最初的 VC 的 fetchrequest 中。 VC 包含一个 table 视图。
- 保存托管上下文
- 切换到第一个 VC,然后重新加载数据
我没有使用 NSFetchResutltsController 来管理这些 returned 对象。当我的 table 视图重新加载时发生崩溃。我确实提出了另一个请求,并希望删除的对象不会被 returned,但确实如此。当我的单元格试图读取已删除对象的 属性 时,它读取 uninitialized
并崩溃。在 2 VC 之间切换时,大约有五分之一会发生这种情况。我在所有 CoreData 函数中都使用了 performAndWait
。
有没有办法解耦两个屏幕之间Managed Objects的关系?如果没有,我如何才能在第一个 VC 中获取我的提取请求,而不是 return 在第二个 VC 中删除的对象,让它们保持同步?
NSManagedObject 不同于其他对象。它本身不包含任何信息。它有一个指向其上下文的指针和一个 objectID。当您访问它的属性时,它会将请求转发到上下文以获取所需的信息。因此,当从上下文中删除实体时,managedObject 停止工作并导致崩溃。这就是为什么总的来说,我认为永远保留指向 managedObject 的指针并始终使用 fetchedResultsController 访问它们是一种不好的做法,即使仅针对一个对象,并且仅在 managedObjects 结果随后被丢弃时才进行提取。
您在问题中暗示了两种可能的解决方案。您可以从 managedObject 中复制值,也可以使用 fetchedResultsController。如果您复制这些值,那么即使在实体被删除后它也会正常显示。如果您使用 fetchedResultsController,那么 fetchedObjects 属性 将永远不会包含已删除的对象,并且该对象在删除后将无法访问。
我建议使用 fetchedResultsController。你不需要害怕它。这不是一个很大的开销,即使您只获取一个对象也可以合理使用。