CoreData Hourly Crash "nilOutReservedCurrentEventSnapshot"

My application crashed, which happens quite rarely (maybe every 30 starts). The error code contains a strange selector name _nilOutReservedCurrentEventSnapshot__ , which I could not find at all. Here is the feed from my console:

 *** 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 

If someone can shed light on the meaning of this phrase _nilOutReservedCurrentEventSnapshot__`, that would help me a lot. Screenshot of the location of the accident below:

Error

+5
source share
3 answers

_nilOutReservedCurrentEventSnapshot__ is a private method on NSManagedObject internally to clear attributes and values ​​from a Core Data object. You can see it in the private header for NSManagedObject here .

__NSCFType is a private wrapper for Core Foundation types used in the internal Objective-C environment. You can learn more by looking at the private headline here , but there aren't many.

Without full backtracking, it is difficult to debug a specific problem. As I see it, there may be two culprits:

  • parentObject your context is somehow invalid.

  • You are trying to save a Core Foundation object as a property in NSManagedObject that does not expect it.

+1
source

Sorry, you cannot find around _nilOutReservedCurrentEventSnapshot__ online ..

This is likely due to the life cycle of the snapshot of the managed entity.

When Core Data retrieves an object from persistent storage, it receives a snapshot of its state. A snapshot is a dictionary of the permanent properties of objects, as a rule, of all its attributes and global identifiers of any objects to which it has a "one" relationship. Pictures participate in optimistic blocking. When the wireframe saves, it compares the values ​​in each image of the edited objects with the current corresponding values ​​in the persistent storage.

The fact that _nilOutReservedCurrentEventSnapshot__ not documented means that this type of behavior should not be.

We know that this is a function of the NSManagedObject class.

Therefore, the error unrecognized selector sent to instance was caused by the fact that _nilOutReservedCurrentEventSnapshot__ was called on an object that was not NSManagedObject , because NSManagedObject was freed, and now something else fills its memory. It is a fact.

The context is not indicated in the question about the nature of the application and its configuration of CoreData, but it is assumed that it uses the parent-child concurrency template. It is important.

Parent-child context template
[Image retrieved from here ]

Of all the questions asked during stack overflow that I can find about this error, it seems that they all use the parent-child concurrency pattern.

It is possible that the problem was caused by the adoption of this template with improper implementation or processing of ManagedObjects.

A A situation in which a parent-child context can be used is the synchronization of cloud data or the processing of changes made when a user edits something with the ability to undo or undo changes made that can be made in the background thread.

The question also mentions that this is a rare occurrence and does not occur every time. This means that the contexts are probably fine until a certain save or change occurs, and somehow the contexts cease to synchronize, and performing another save will cause the application to crash.

In the documents Synchronization of changes between contexts:

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

Changes will be sent to the parent context when the child is saved, but not if the parent has been changed separately. It is highly recommended that you never change the parent context; only by preserving the childish context and spreading the changes from there.

Possible cause of failure



There are a few things that can cause this, but two that stick out:

1. Release ManagedObject from the link, which is removed due to a rejection of the modal view in the application or iOS sheet in the OSX application.

possible solution: set the retainsRegisteredObjects property of the child context to true before retrieving ManagedObjects (and then set it to false as soon as the contexts are saved to avoid further potential memory leaks). a warning!

eg. ctx.retainsRegisteredObjects = true



2. Raw changes in context.

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

Consider an application with two contexts of managed objects and one permanent repository coordinator. If the user deletes the object in the first context (moc1), you may need to inform the second context (moc2) that the object was deleted. In all cases, moc1 automatically sends an NSManagedObjectContextDidSaveNotification notification through the NSNotificationCenter, which your application must register and use as a trigger for any action that needs to be taken. This notification contains information not only about deleted objects, but also about changed objects. You need to process these changes because they may be the result of deletion. Most of these types of changes are related to transitional relationships or derived properties.

Possible solutions:



Since there is no other information to deduce what causes the error, and I cannot reproduce it .. I would suggest trying to find where your ManagedObject freed using Zombie profiling in tools.

If a message is sent to one of these freed objects (which are now NSZombie objects), a zombie sign is placed, the application crashes, recording stops and the Zombie Messaged dialog box appears. You can then study the history of saving and freeing a zombie object to pinpoint where the problem arose.

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

Hopefully then someone can shed light on what caused the problem.

in +++++++++++++++++++++++++++++++++++

Side note:
parent / child contexts can lead to stuttering from the user interface - "every request for selection, and each save operation completely blocks the main stream when data is read or written to / from the disk." This is because each selection is pulled through the parent context (in the main thread) for the child.

SO response support

It is recommended that if you use this approach, you will rethink the project as something like two independent contexts of managed objects associated with the same permanent repository coordinator , which may "avoid" the problem in the future in the future.

Two contexts one coordinator [Image retrieved from here ]

You can see dramatic performance differences in a related article

+1
source

Wild hunch .. Is there any chance of calling this save method from a different thread than the actual thread that created the context? For the safer side, always perform the Save: operation from / PerformBlockAndWait.

0
source

Source: https://habr.com/ru/post/1244184/


All Articles