Iphone Core Data Internal Inconsistency - iphone

This question has something to do with the question I posted here: Iphone Core Data crashing on Save
however the error is different so I am making a new question. Now I get this error when trying to insert new objects into my managedObjectContext:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '"MailMessage" is not a subclass of NSManagedObject.'
But clearly it is:
#interface MailMessage : NSManagedObject { ....
And when I run this code:
NSManagedObjectModel *managedObjectModel = [[self.managedObjectContext
persistentStoreCoordinator] managedObjectModel];
NSEntityDescription *entity =[[managedObjectModel entitiesByName]
objectForKey:#"MailMessage"];
NSManagedObject *newObject = [[NSManagedObject alloc] initWithEntity:entity
insertIntoManagedObjectContext:self.managedObjectContext];
It runs fine when I do not present an MFMailComposeViewController, but if I run this code in the
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
method, it throws the above error when creating the newObject variable.
The entity object when I use print object produces the following:
(<NSEntityDescription: 0x1202e0>) name MailMessage, managedObjectClassName MailMessage,
renamingIdentifier MailMessage, isAbstract 0, superentity name (null), properties {
in both cases, so I don't think the managedObjectContext is completely invalid. I have no idea why it would say MailMessage is not a subclass of NSManagedObject at that point, and not at the other.
Any help would be appreciated, thanks in advance.

Class MailMessage could be implemented in a library or somewhere else in the framework. As Objective C does not implement namespaces, one of the two will be used. Which one is undefined. Try giving your class a different name to quickly resolve the issue.

Look for a message like this from the debugger. It will confirm what Benjamin says.
Class MailMesssage is implemented in both /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk/System/Library/PrivateFrameworks/Message.framework/Message and /Users/home/Library/Application Support/iPhone Simulator/4.2/Applications/FFFFFFFF-FFFF-0000-0000-AAAAAAAAAAA/Projects.app/Projects. One of the two will be used. Which one is undefined.

Try resetting the Simulator or uninstalling the application from your device. Often the NSInternalInconsistencyException has to do with problems with changing the datamodel and the database not being updated accordingly.

I was able to workaround this by creating the MailMessage object before presenting the modal view controller. Once the MailMessage object was already created, saving changes did not present a problem. A strange workaround and not addressing the actual problem as far as I know, but it works.

Related

'NSInternalInconsistencyException', reason: "Foo" is not a subclass of NSManagedObject

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];

JSON to core-data

I am trying to save JSON response to local core-data for my app. I am following the following implementation for this:
https://stackoverflow.com/a/2363996/127036
Here is my code:
NSString *objectName = #"Post";
NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:objectName inManagedObjectContext:moc];
[managedObject setValuesForKeysWithDictionary:structureDictionary];
Compiler returns following error:
-[__NSCFDictionary entity]: unrecognized selector sent to instance 0x6dc6fa0
While trying to execute:
setValuesForKeysWithDictionary
Please guide me in the right direction to fix this issue.
I'm not seeing setValuesForKeysWithDictionary in the dev center for NSManagedObject
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/Reference/NSManagedObject.html
You may have to loop through and do them one at a time with setValue:forKey:
This post is quite old now and I'm sure the Vibhor Goyal has already moved on. But in case anyone runs into this same problem, the reason why he's getting
-[__NSCFDictionary entity]: unrecognized selector sent to instance
Is because in his Post model, I'm sure he has sub entities, probably something like "comments" which is probably a to-many relationship to a "Comment" model.
Then in his structureDictionary, he probably has the usual key-value fields that corresponds to his Post model, and for the "comments" key he probably has a NSSet of NSDictionaries for the value.
So the reason why he's getting that entity selector error is because under the hood, core data is expecting "comments" to be a set filled with instances of "Comment" which are supposed to be instances of NSManagedObject, but instead it's getting instances of NSDictionary. So when it asks for "entity" from each of the "comments" it throws the unrecognized selector error.
Hope this helps someone in the future.

Bug with message sent to deallocated UITableViewController object by framework code

I am developing my first iPhone app for a couple of months and now I got stuck on a memory error “message sent to deallocated instance”. I have written down all my observations (from the debugger) but can't find the reason. I will really appreciate any help.
SITUATION:
I have created pick_ListBrowseController, a subclass of UITableViewController.
It is called to pick an item from a scrolling list. The objects presented come from a CareData database.
I useNSFetchedResultsController.
In the implementation of pick_ListBrowseController, there is a typical method returning a fetched results controller:
- (NSFetchedResultsController *) fetchedResultsController {
// If the fetched results controller already exists, return it:
if (fetchedResultsController != nil) { return fetchedResultsController;}
(…) // constructing fetchRequest object with entity and sort descriptors
[NSFetchedResultsController deleteCacheWithName:#"pick_List"];
// Create fetched request controller:
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil cacheName:#"pick_List"];
// Set the fetched results controller's delegate to self;
// it will send controllerDidChangeContent:
[aFetchedResultsController setDelegate: self];
// Assign this new fetched results controller to the property:
[self setFetchedResultsController: aFetchedResultsController];
// Return fetched request controller:
return fetchedResultsController;
}
BUG SCENARIO A:
STEP 1) I call my pick_ListBrowseController, select an item and navigate back. The view disappears.
In the debugger, I can see that the pick_ListBrowseController object had memory address 0x729b950
STEP 2) I call pick_ListBrowseController once again. It is now another instance, with memory address 0x755a4e0
STEP 3) When I try to pick an item, I get error message:
[pick_ListBrowseController controllerDidChangeContent:]: message sent
to deallocated instance 0x729b950.
The address is from STEP 1) ! For some reason, the framework code (which is not accessible for me) sends controllerDidChangeContent: to the already deallocated object from STEP 1), not to the object from STEP 2), as it should.
BUG SCENERIO B:
Even worse, it happens even when in STEP 1) I call a different controller object , also a subclass of UITableViewController. Steps 2) and 3) remain the same. The same bug occurs and in the debugger I can see that even now controllerDidChangeContent: is sent to the object from STEP 1). Hence it is sent not only to the wrong (and deallocated) object, it is even sent to an object from a different class!
QUESTIONS:
1) What may be the reason? How to fix it?
2) My app is really big. Is it possible that it became too big causing the memory problems described above? If yes, what can I do to get things right?
Currently, I use Xcode Version 4.2 build 4C199 and I use Automated Reference Counting (ARC) - I went through the refactor process “convert to Objective-C ARC”.
Any help will be highly appreciated.
It is likely that your FRC is not getting released when your VC is dealloc ed. If it is hanging around and has your VC as a reference to the delegate then you have a dangling pointer. Double check that you are cleaning up the FRC.

CoreData (storing new object) in AppDelegate = SIGABRT

I've intented to make a simple function in AppDelegate to store some data in database (CoreData) which would be called from various ViewController classes connected do AppDelegate. This is the body of this function:
- (void) setSetting:(NSString *)setting :(NSString *)value {
NSManagedObject* newSetting = [NSEntityDescription insertNewObjectForEntityForName:#"EntityName" inManagedObjectContext:self.managedObjectContext];
[newSetting setValue:value forKey:setting];
NSError* error;
[self.managedObjectContext save:&error];
}
But calling this function (even from AppDelegate itself) returns SIGABRT on line with setValue
But when I implement the function in ViewController class (replacing self. with proper connection to AppDelegate of course) - it works fine.
I don't get it and I would really appreciate some help in creating flexible function in AppDelegate to save the data in database.
This looks a bit like the key part is not an NSString or the value part is not the correct data type. Please check, and perhaps make the order of the arguments in your function the same as in the setValue:forKey method to avoid confusion.
Also, according to the documentation, an exception will be raised if the key is not defined in the model - so double-check your key strings.
BTW, if this is your error it is a good idea to move away from KVC and create your own NSManagedObject subclasses instead as a habit - makes life much easier.
The most likely explanation is that this line:
NSManagedObject* newSetting = [NSEntityDescription insertNewObjectForEntityForName:#"EntityName" inManagedObjectContext:self.managedObjectContext];
… returns a nil object either because the entity name is incorrect or because the managedObjectContext is itself nil or otherwise invalid.
Since the problem only occurs in the app delegate, I would first suspect some issue with self.managedObjectContext.

Cocoa-Touch, Core Data: Getting exception when trying to insertNewObjectForEntityForName:inManagedObjectContext:

I'm following this how-to to implement Core Data storage in my app:
I have a Model.xcdatamodel which defines a Something model. I've used XCode to generate a class for that model.
I've imported the class in my .m file where I'm trying to:
Something* s = (Something *)[NSEntityDescription insertNewObjectForEntityForName:#"Something" inManagedObjectContext:managedObjectContext];
But this causes the following error:
2009-10-13 21:18:11.961 w9a[4840:20b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Something''
Am I missing something?
Personally, I prefer the following method:
// With some NSManagedObjectContext *context
NSEntityDescription *desc = [NSEntityDescription entityForName:#"Something"
inManagedObjectContext:context];
Something *s = [[[Something alloc] initWithEntity:desc
insertIntoManagedObjectContext:context] autorelease];
I've noticed it's less prone to random Core Data errors, and is easier to debug. It's effectively doing the same thing as your code, but explicitly gets an entity description first, so you can debug that separately if need be.
Seems that you dont have a NSManageObject named "Something" in your object model...are you making your entity in the object model? I am not sure if you need to generate the code as well, but you can have xcode do that for you automatically by clicking on the entity, saying new, and selecting Managed Object from the menu there
Found my problem, the NSManagedObjectContext was not geting initialized properly for some reason. I've re-written that code following the how-to and now it seems to work.
Thanks anyway :)