views:

551

answers:

3

I'm using core data on an iPhone application. I have multiple persisntent stores that I'm switching from one to another so that only one of the stores can be active at the time. I have one managed object context and the different persistent stores are similar in data format (sqlite) and share the same managed object model.

I'm importing the data to each persistent store from a respective XML file. For the first import everything works fine, but after I remove the imported data (the persistent store and the physical file) and then re-import, core data gives me an error:

*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'The NSManagedObject with ID:0x3c14e00 <x-coredata://6D14F11E-2EA7-4141-9BE8-53747DE6FCC6/Book/p2> has been invalidated.'

This error comes from the save: of NSManagedObjectContext. Before re-importing, i'm removing the persistent store from the persistent store coordinator and removing the physical file, so everything should be as if re-importing was done for the first time. Alos, the objects in managed object context are removed and the context is sent the reset: message (I don't know if this is actually needed).

Could some one help me out here? How should the persistent store be switched?

I'm basically using the same logic as tutored here: http://blog.sallarp.com/iphone-core-data-uitableview-drill-down/

Thanks in advance.

Update on the goal

Thank you for your answers.

Apologies for the vagueness on my goal. I'm developing a Bible reader application that would import translations from XML to core data SQL. Currently only one translation can be in use. Currently I only have different MOC and PS for each translation since the model is the same. I do believe, however, if you say that the stack should be created as a whole. The translations have no connections between each other, so there is no actual reason for using the same stack. The only thing that could complicate this would be notes/bookmarks/etc that will reference to the active translation. The references, however, will be textual so again there is no necessary need for a shared stack.

Thank you for your input.

+1  A: 

It is almost certainly the case that the NSManagedObjectContext you are using still has internal references to an object that is backed by the detached persistent store. The simplest way to handle this is to not reuse the context.

It is unclear to me why you are reusing the same persistent store coordinator or managed object context. If these are really conceptually separate sets of things (such that you will only work with one at time) why are you trying to reuse an existing stack with potentially stale state in it (which is what is causing your issues).

Creating and destroying NSManagedObjectContexts is really lightweight. Creating a full new PSC is a bit heavier, but in the scale of what you are doing (moving files and importing XML) it is probably not measurable either.

Louis Gerbarg
Thank you for the answer. What I don't understand is why there are any entities left in the context if it is emptied and reset and I'm add new to it. I'm pretty green with obj-c/cocoa, so sorry for any confusion.I'm not trying to reuse or save any resources right now since this'll be done very rarely. Basically I will have different translations but at the moment I'm using only one. I wouldn't want to limit anything if there is no need for it.So using different contexts for different translations would serve better in this case? The contexts would share exaclty the same model though.
mkko
+1  A: 

I agree with Louis, what you are doing is a dangerous design and you should be rebuilding the entire stack instead of swapping out the stores like that. Rebuilding the full stack is not a huge overhead.

Also, if you are using completely different models with completely different data objects you don't need to remove them, you can add all of the models together into one persistent store and based on which entity you create, Core Data will do the right thing.

If you are building multiple models with the same entity then the question is why? You are not going to get any performance benefits out of it.

Update

In the situation you have described I would put all of the stores into a single persistent store coordinator and then instruct the context which store to save the entity with -assignObject:toPersistentStore:. That will eliminate the need to build up and tear down multiple Core Data stacks.

Update 2

A new stack is the entire stack. The PSC, the MOM and the MOC. You are pulling the rug out from under the Core Data stack and then expecting it to just figure out what you are doing.

What is your end goal?

Late Update

Um, so what would be an acceptable scenario for creating only the PS and MOC and using existing PSC and MOM? If I guessed, I'd say that every time I made modifications to the existing stack, it should be created anew and that if multiple stores were used, they should be introduced at the time of the construction.

The NSManagedObjectModel, NSPersistentStoreCoordinator and NSPersistentStore are tied together rather tightly so it is unclear what your goal is here. If you update your question with what you are trying to accomplish it will make answers a lot less vague.

Having multiple NSManagedObjectContext instances is normally used when you are dealing with multiple threads and a few very rare edge cases. Having multiple NSPersistentStore instances is normally used when you have data that needs to be silo'ed for one reason or another (partially read only, etc.). Those are the normal use cases.

My question still stands though, what are you trying to accomplish?

Update on goal

I'm developing a Bible reader application that would import translations from XML to core data SQL. Currently only one translation can be in use.

Ok, you do not need separate files for each translation, that is a waste. Since each translation is identified by a code (such as ASM) and name, copyright, etc. you can simply create a top level entity in your design that is called ... "Translation" and the rest of the data branches from there. No multiple contexts, no switching things around, it just works.

The only time you need multiple files is if you are in a multi-document design which is not something you do on the iPhone.

Marcus S. Zarra
As I replied already to Louis, I'm trying to implement a way to switch between the physical storages, each containing a different translation. I understood that the managed object context could be shared between the translations, but apparently it would be safer to use different one for each of them.Would this way be somewhat less dangerous? Would the rebuilding the stack mean a new persistent store coordinator also? If I understood correctly, I'd only have to create a new context and store and use them together. Thank you for your input.
mkko
In response to Update2: Basically what I'm doing is switching between different translations of the SAME source with identical model. Later on I might have multiple persistent stores, one for each translation, but now I only would have them as imported files. Should I create the stack separately for EACH of the translations? They would share the identical MOM though. Once again, I'm not trying to optimize, I'm only trying to simplify things.
mkko
Um, so what would be an acceptable scenario for creating only the PS and MOC and using existing PSC and MOM?If I guessed, I'd say that every time I made modifications to the existing stack, it should be created anew and that if multiple stores were used, they should be introduced at the time of the construction.
mkko
I'm new to Stack Overflow and I don't know if the update on the question was notified, but I added a reply to the "Late Update". Apologies for muddled responses, I'm not always sure where to reply.
mkko
Are you sure there's no performance issues when storing into the same file each of the translations? I mean that one translation will consume about 5 to 10 megabytes. Only one translation will be active at the time (currently) and the swapping of a store would be done very rarely.If so, if I kept the translation files separate, should I handle them in completely different stacks (MOM, PSC, PS and MOC)?
mkko
Quite certain, you are storing the data in a SQLite database not a flat file so you are going to only load the data that is relevant. SQLite has been used for databases that are terabytes in size and retains it's performance.
Marcus S. Zarra
A: 

can u post the sample code... coz i am also facing the same issue.. Thanks

Raks
I would gladly, after I've learned the right way to do this. I don't want to mislead anyone with bad examples.
mkko