How I am Currently Using Core Data:
My app loads: On this page i create a Managed Object Context, fetch the managed objects, and load / display them. This is a tableview so I allow deleting. In order to delete i create a managed object context and delete the managed object and reload the tableview. This same method is used throughout my app, there are other operations such as updating ect ect. The main point is for each action i create a new managed object context.
My current understanding of Core Data is that a Managed Object Context is sort of like a queue, that fills up with actions. Where as the Managed Object is the item being modified and placed into the queue for an action to occur. Using this logic, shouldn't there only be one queue throughout the entire app?
Main Question:
Do I need to create a managed object context before every action? or could i create one managed object context say in app delegate did finish launching? and utilize this throughout the entire app?
Edit:
For future viewers(and if i understood the answers provided) my code now generally looks like this:
ManagedObjectContext
.Throughout my app as I need to make changed to my core data objects, I do the following:
if let managedContext = ShareData.sharedInstance.managedObjectContext {
// DO STUFF, update, delete, create ect ect ect
}
Edit 2: I may have misinterpreted the "Do not create MOC in App delegate", Currently looking into this and attempting to learn best placement for the creation of MOC. Seems tedious to create one elsewhere if EVERY view you can possibly start the app on requires the MOC.
You should really only need to create one core data stack throughout the lifetime of the app. (There are exceptions to this but for most apps).
I am currently using JSQCoreDataKit to manage the creation of the stack and saving contexts. It would definitely be worth taking a look at this.
The normal approach to core data is something like...
Create the core data stack on launch of the app. Normally accessed through a singleton (NOT IN THE APP DELEGATE).
For reading data from core data get the mainContext
from the core data stack and perform fetches on this mainContext
.
For writing (adding, updating, deleting) data back you can use the mainContext
but can also get a backgroundContext
or childContext
from the core data stack. The perform the updates and saveContext
inside a perform
block on the context. (This will merge changes to the main context for you to read).
This should cover most of what you want to do.
Have a look at JSQCoreDataKit. It makes the creation of the managed object context much much simpler.
Putting things into the AppDelegate is a very clunky and lazy way to get at data across the board. The AppDelegate is a singleton so it seems like the perfect place to put it. But then you add more and more and suddenly you have a huge app delegate that drives your entire app.
Using the Single responsibility principle your app delegate should do one thing... be a delegate for you app. It should respond to app state changes etc...
I forgot to add... If you create a second target (say a TVOS target) for your app. It will not use the same AppDelegate. If all your CoreData code (and other code) is inside the AppDelegate then the TVOS app will not be able to access it. Putting it in another class that is accessible to both apps means that both apps can share the code you use for CoreData (et al).
It is very easy to create another file that holds your core data stack and initiate it whenever you first need access to core data. (Not necessarily from the AppDelegate but from the first place you need to make a read/write).
RE placing the core data stack setup in the initial view controller. You could do that. You then have the issue of how do you get to that core data stack from every other view controller in the app. You could either make the initial view controller a singleton (don't do this) or you could pass the stack around.
Both approaches can be done but CoreData is inherently a singleton. There is only one set of data on your phone's disc. So creating a singleton here is not a bad thing.
If you do make a singleton then make it purely a core data stack singleton. I have one called something like CoreDataStackManager
. All it does is hold the coreDataStack
property.