I got the following error when deleting an object from my app. Any ideas on how to fix it?
I'm still trying to recreate the process to find out exactly where it is crashing.
Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. CoreData could not fulfill a fault for '0x5adc8b0 <x-coredata://2B90C6EC-E046-4508-A1B1-6C4B19BF830D/Session/p1>' with userInfo {
NSAffectedObjectsErrorKey = (
"<Session: 0x6f7c830> (entity: Session; id: 0x5adc8b0 <x-coredata://2B90C6EC-E046-4508-A1B1-6C4B19BF830D/Session/p1> ; data: <fault>)"
);
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x5adc8b0 <x-coredata://2B90C6EC-E046-4508-A1B1-6C4B19BF830D/Session/p1>''
A) If you are subscribing to save notifications, Core Data is pointing to a failure there.
B) The "could not fulfill a fault" message is often related to deleting an object, after which some other part of your app tries to access ANY property on it. Yes, even ones where faults were previously fulfilled. The whole object is unusable after a delete.
This occurred in my code when I passed a managed object down to a custom NSOperation class. My NSOperation would load other objects through its to-many relationship, process them, then delete those objects. If it tried to do a search on more objects in the to-many relationship, it would sometimes crash with the "CoreData could not fulfill a fault" exception. Then I remembered reading about "thread confinement" in the Core Data Programming Guide so I changed my code to pass a key down to my NSOperation class. The NSOperation class would then do its own search in its own context to find its own instance of the core data class. I stopped getting the exception after that. (I still have to use save notifications.)
Related
After adding a new NSManagedObject to my Core Data store I tried calling:
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
and got the following exception (weirdly I had no error and the result was also positive!)
2013-03-15 18:32:09.753 Nick copy[28782:3407] CoreData: Ubiquity: An exception occured during a log file export: NSInternalInconsistencyException save notification contents: NSConcreteNotification 0x3891b0 {name = _NSSQLCoreTransactionStateChangeNotification; object = (URL: file://localhost/var/mobile/Applications/FCAF7FC6-7DC8-4E0B-A114-38778255CA90/Documents/MyApp.sqlite); userInfo = {
"_NSSQLCoreActiveSaveRequest" = "";
"_NSSQLCoreTransactionType" = 2;
"_NSSQLCoreTransientSequenceNumber" = 1;
}}
I can catch all exceptions from the "save" method and the App runs fine. Just wondering if this is really save to do, because it feels totally unsafe.
EDIT: Another exception when trying to delete an Object:
Catched Exception: Failed to process pending changes before save. The context is still dirty after 100 attempts. Typically this recursive dirtying is caused by a bad validation method, -willSave, or notification handler.
Is it safe? Probably not. The error shows that the underlying ubiquity system failed to create a SQL log file. That probably means that it failed to create the transaction log that iCloud would use to sync changes. Catching it and continuing means that your data probably saved locally, depending on the details of the framework code. But it almost certainly means that the changes will not be synced by iCloud. Worse, you could well be in a situation where future saves will also fail for the same reason.
I'm not completely sure about the second exception but it's very likely to be a side-effect of the first one.
If you're attempting to use Core Data's built-in iCloud support on iOS5, this is just the beginning of the weird, inexplicable errors. I've done a fair amount of iCloud/Core Data work and I really can't recommend using it with iOS 5. Even iOS 6 is dicey at best, but problems are less likely than on iOS 5.
Unfortunately I can't find the thread anymore, but it told me I had to make sure to always use NSManagedObject classes only in the thread/dispatch_queue in which they are created.
The problem is, if you do access it from a different queue, it might work or crash after a random interval.
I made sure I call NSManagedObject from a dedicated dispatch_queue only and have not logged any weird exceptions since then.
I have a strange problem here. I am not getting the callbacks for "Update" operations on my NSManagedObject, but where as any objects inserted into or removed from the collection of that entity type would trigger the delegate callbacks.
Before I proceed with the question further, I would like to inform about my setup:
NSFetchedResultsController is properly configured. Made sure that
the property which is being modified externally is not any of the
sort keys for the fetchedResultsController as required by this Apple
documentation:
An update is reported when an object’s state changes, but the changed
attributes aren’t part of the sort keys.
There is only single managed object context in which these modifications are happening.
Since insert and delete operations are being reported to the
delegate, I presume there is something fishy about the Update
operations
I was drilling down the Restkit code with help of RKLogs to see where exactly the mapping happens and where the coredata object is being updated to find out the reason why am not getting the update delegate callbacks.
In the class RKManagedObjectMappingOperation -performMapping method, Mr. Blake Watters has documented the reason why MOC callbacks are not triggered upon updates:
- (BOOL)performMapping:(NSError **)error
{
BOOL success = [super performMapping:error];
if ([self.objectMapping isKindOfClass:[RKManagedObjectMapping class]]) {
/**
NOTE: Processing the pending changes here ensures that the managed object context generates observable
callbacks that are important for maintaining any sort of cache that is consistent within a single
object mapping operation. As the MOC is only saved when the aggregate operation is processed, we must
manually invoke processPendingChanges to prevent recreating objects with the same primary key.
See https://github.com/RestKit/RestKit/issues/661
*/
[self connectRelationships];
}
return success;
}
But I cannot for the life of myself figure out how to fix this? Coz it was done purposefully?
Has anyone faced same problem? How do I fix it?
Thanks,
Raj Pawan
There was 1 mistake from my part and 1 other thing (Ignorance) which I was not aware of and due to which I faced this problem:
Mistake:
Despite many discussion all over the forums, I was wrong to state my second listed item:
There is only single managed object context in which these
modifications are happening.
I had wrongly logged and found out that I was in the same context! So dumb of me!
Ignorance:
I did some digging through the RK code thinking something fishy is going on there, checked Blake Watters' comments and his commit 4b394f8c1e1f to see if the earlier code there (call to -processPendingChanges) which is now removed was causing any issue and not letting the delegate to be informed about updates.
Found out that this was indeed on a separate thread and yes it had its own MOC which I had missed out. Next thing to do was simple, I implemented the mechanism to merge changes of a MOC from different thread into main MOC. But this did not work either!
The reason turns out that I am in a very initial stages of the development of application. I am just mapping the json response with coredata objects using RestKit and I am nowhere utilising it! I was just logging the coredata objects in GDB and they remained in their fault state always! I was relying upon the -objectLoader callbacks and the NSNotification object to see that there was indeed an Update available. At some point while testing I happened to log a property of the managed object which is changed in the Notification callback before it was merged back to the main MOC. This faulted the managed object and loaded all properties of the managed object. Now when the secondary thread MOC changes were merged with the main thread MOC, my NSFetchedResultsControllerDelegate callbacks started triggering.
Ok so this is the error I'm getting
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '"Place" is not a subclass of NSManagedObject.'
I assume that what it means is that 'Place' hasn't been added as an entity to the core data model??? But it has as shown by the image below.
I'm guessing that my assumption is incorrect though so any help or ideas would be nice.
I'm pretty certain that this is the line that's causing it:
NSManagedObject* place = [NSEntityDescription
insertNewObjectForEntityForName:#"Place"
inManagedObjectContext:context];
If you aren't using custom classes (no Place.[hm]), as it sounds like you're not, check the Entity tab, and make sure the Class name is blank (= NSManagedObject) – not Place.
I had the same problem with classes called Message and Connection. The error just appeared after adding an emailing facility using the MessageUI library. I believe the conflict occurs because the library will have classes named Message and Connection, therefore they are not seen to be subclasses of NSManagedObject. Changing their names by prefixing (in my case with an X) makes the entities unique. I intend prefixing all my entities in future so that there is less chance of the conflict arising.
The first thing to do when you encounter this kind of errors is to verify the class name of your entity :
Open XCDataModel
Select your entity
Open the right pane Utilities
Click on "show the data model inspector" button
Verify the class name so that it's in sync with your generated model
Hope this helps !
The other way to address this issue is to indeed use the NSManagedObject subclass (recommended).
Place *place = [NSEntityDescription
insertNewObjectForEntityForName:#"Place"
inManagedObjectContext:context];
Using CoreData (on an iPhone app) I generated my entity classes from the model and I added some more methods to some ones. It appears that sometimes I get an exception for calling one of those methods. The exception is not random but concerns only some ManagedObject subclass (the others seem to respond correctly).
Here is an example of what i get:
-[NSManagedObject printTime]: unrecognized selector sent to instance 0x5b50af0
2010-07-15 10:29:55.216 LP[6686:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObject printTime]: unrecognized selector sent to instance 0x5b50af0'
The NSManagedObject is an object I get from a fetch (casted to the correct subclass), and the methods I am talking about are printing methods. (I tried to retrieve those not as faults either)
Am I missing something?
Did you set the correct class for the entity in the managed object model?
I tried to save data and merge with CoreData and multi-thread for iPhone app.
But I can't get managed objects in the main thread after merging.
I wrote code just like this:
[managedObjectContext performSelectorOnMainThread:#selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
[self performSelectorOnMainThread:#selector(didMerged:) withObject:objectIds waitUntilDone:YES];
So I tried to pass objectIds to get NSManagedObject instances in the main thread which were generated in another thread. At first I tried "objectWithId" method but it generated fault objects. Then I tried "existingObjectWithID" method but it generated objects partly and others were nil with following Error:
[Error] Error Domain=NSCocoaErrorDomain Code=133000 "Operation could not be completed. (Cocoa error 133000.)"
What is wrong? Is there any way how to retrieve all objects by objectIds after merging in another thread?
Thank you.
There are two types of object ids. Before you save a NSManagedObject it has temporary object id. After saving, it will get its final id. So you may use the wrong id...
Read Managed Object IDs and URIs here: https://developer.apple.com/documentation/coredata/nsmanagedobjectid
It seems your context merge failed.
developer documentation on error 133000
NSManagedObjectReferentialIntegrityError = 133000
NSManagedObjectReferentialIntegrityError
Error code to denote an attempt to fire a fault pointing to an object that does not exist.
The store is accessible, but the object corresponding to the fault cannot be found.
Available in Mac OS X v10.4 and later.
Declared in CoreDataErrors.h.
First, you need to unroll your errors. Change the output to:
NSLog(#"Error: %#\n%#", [error localizedDescription], [error userInfo]);
That will give you a lot more information.
Second, if you are working with a single context in multiple threads you are doing it wrong. You need to review the documentation on Core Data and threading. The basic rule is: One Context Per Thread; Period. If you need to manage data across multiple threads look into watching the save notifications from the background threads on the main thread. I would suggest reviewing my articles on the Mac Developer Network for examples of this.