gpt4 book ai didi

ios - 罕见的 CoreData 崩溃 "nilOutReservedCurrentEventSnapshot"

转载 作者:可可西里 更新时间:2023-11-01 03:56:42 27 4
gpt4 key购买 nike

我的应用程序中发生了崩溃,这种崩溃很少发生(可能每 30 次运行一次)。错误代码包含一个奇怪的选择器名称 _nilOutReservedCurrentEventSnapshot__我根本找不到任何文档。这是来自我的控制台的提要:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType _nilOutReservedCurrentEventSnapshot__]: unrecognized selector sent to instance 0x157b51e0'
*** First throw call stack:
(0x2358810b 0x22d2ee17 0x2358d925 0x2358b559 0x234bbc08 0x24cbf445 0x24ca4d99 0x249bec 0x245c90 0x19b68c 0x24a5c97 0x24b05ab 0x24a8ef9 0x24b1a8d 0x24b18e7 0x232bfb29 0x232bf718)
libc++abi.dylib: terminating with uncaught exception of type NSException

如果有人能够解释这个短语 _nilOutReservedCurrentEventSnapshot__` 的含义,那将对我有很大帮助。崩溃位置截图如下:

The error

最佳答案

不幸的是,您找不到关于 _nilOutReservedCurrentEventSnapshot__ 的太多信息。
在线的..

它可能与托管对象的快照生命周期有关。

When Core Data fetches an object from a persistent store, it takes a snapshot of its state. A snapshot is a dictionary of an object’s persistent properties—typically all its attributes and the global IDs of any objects to which it has a to-one relationship. Snapshots participate in optimistic locking. When the framework saves, it compares the values in each edited object’s snapshot with the then-current corresponding values in the persistent store.



事实 _nilOutReservedCurrentEventSnapshot__没有记录意味着这种行为不应该发生。

我们所知道的是,它是 NSManagedObject 的函数。类(class)。

因此错误 unrecognized selector sent to instance是因为 _nilOutReservedCurrentEventSnapshot__在不是 NSManagedObject 的对象上被调用,因为 NSManagedObject被释放,其他东西现在填满了它的内存。这是事实。

关于应用程序的性质及其 CoreData 设置的问题没有给出上下文,但推断它正在使用 父子并发模式 .这个很重要。

Parent-Child context pattern
[图像检索自 here ]

从我可以找到的有关此错误的有关堆栈溢出的所有问题中,它们似乎都使用父子并发模式。

该问题完全有可能是由于采用此模式以及对 ManagedObjects 的不正确实现或处理造成的。

可以使用父子上下文的一种情况是同步云数据或处理用户编辑某些内容时所做的更改时,可以选择放弃或撤消所做的更改,这可以在后台线程上完成。

问题中还提到,这是一种罕见的情况,并非每次都会发生。这意味着上下文可能很好,直到进行了某个保存或更改,并且上下文以某种方式变得不同步,并且执行另一个保存会使应用程序崩溃。

从关于在上下文之间同步更改的文档:

If you use more than one managed object context in an application, Core Data does not automatically notify one context of changes made to objects in another. In general, this is because a context is intended to be a scratch pad where you can make changes to objects in isolation, and you can discard the changes without affecting other contexts.



保存子级时,更改将发送到父级上下文,但如果父级已单独更改,则不会。强烈建议您永远不要更改父上下文;只有通过保存子上下文并从那里传播更改。

Possible reason for crash

有几件事可能会导致这种情况,但有两个突出的是:

1. 从由于关闭 iOS 应用程序中的模态视图或 OSX 应用程序中的工作表而处置的引用中释放 ManagedObject。

可能的解决方案:设置 retainsRegisteredObjects子上下文的属性为 true在获取 ManagedObjects 之前(然后在保存上下文后设置为 false 以避免进一步潜在的内存泄漏)。 warning!

例如。 ctx.retainsRegisteredObjects = true
2. 未处理的上下文更改。

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/ChangeManagement.html#//apple_ref/doc/uid/TP40001075-CH22-SW1

Consider an application with two managed object contexts and a single persistent store coordinator. If a user deletes an object in the first context (moc1), you may need to inform the second context (moc2) that an object has been deleted. In all cases, moc1 automatically posts an NSManagedObjectContextDidSaveNotification notification via the NSNotificationCenter that your application should register for and use as the trigger for whatever actions it needs to take. This notification contains information not only about deleted objects, but also about changed objects. You need to handle these changes because they may be the result of the delete. Most of these types of changes involve transient relationships or fetched properties.



这里可能的解决方案是:
  • 在您的上下文中使用块方法。 refer to callback function at bottom of linked file.
  • 确保使用 objectWithID在上下文之间传递 ManagedObjects 时。
  • 使用 NSManagedObjectContextDidSaveNotification 对对象更改采取适当的措施扳机。
  • 删除对 ManagedObject 的所有强引用。可能对在给定代码范围之外使用的 ManagedObject 进行了强引用,因此当父级解除分配 ManagedObject 而子级没有释放时,在将来的保存中,子级对该 ManagedObject 执行了另一次保存,并且然后父上下文尝试保存已解除分配的 ManagedObject。
    "it is a good pattern to try to fetch objects, modify them, save them and reset the edit [child] context"

  • 因为这里没有其他信息来推断导致错误的原因,我无法重现它..我建议尝试找到您的 ManagedObject 的位置。使用仪器中的僵尸分析解除分配。

    If a message is then sent to one of these deallocated objects (which are now NSZombie objects), the zombie is flagged, the app crashes, recording stops, and a Zombie Messaged dialog appears. You can then examine the retain and release history of the zombie object to determine exactly where the problem occurred.



    https://github.com/iascchen/SwiftCoreDataSimpleDemo/blob/master/SwiftCoreDataSimpleDemo/CoreDataHelper.swift

    希望然后有人可以更多地了解导致问题的原因。

    +++++++++++++++++++++++++++++++++++++

    旁注:
    父/子上下文可能导致 UI 卡顿 - “every fetch request and every save operation will fully block the main thread while data is read or written to/from disk”.这是因为每次获取都是通过父上下文(在主线程上)拉到子上下文中的。

    supporting SO answer

    建议您在使用这种方法时重新考虑设计,例如将两个独立的托管对象上下文连接到同一个持久存储协调器 这可能会“避免”将来发生手头的问题。

    Two contexts one coordinator
    [图像检索自 here ]

    您可以在 linked article 中看到巨大的性能差异。

    关于ios - 罕见的 CoreData 崩溃 "nilOutReservedCurrentEventSnapshot",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35717135/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com