Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Context pattern? Why does Core Data need it?

I'm still fairly new to Core Data and am trying to understand why it requires the passing around of a NSManagedObjectContext. As I understand it, passing the context is needed so that multiple threads don't affect the same context, but I was also under the impression that this pattern is sometimes considered an antipattern, as noted here.

Could Core Data theoretically be implemented in a thread safe way that would avoid using this pattern? How do other ORMs (such as Ruby's ActiveRecord for example) avoid this pattern? For example, couldn't CoreData implement a per-NSManagedObject saving method such as in this extension. This light framework doesn't handle multithreading, but couldn't NSManagedObjects use some kind of internal GCD queue(s) to support it, with an internal context they don't expose?

Sorry if I'm missing anything major.

like image 952
donalbain Avatar asked Jun 24 '11 15:06

donalbain


People also ask

What is context in Core Data?

From your perspective, the context is the central object in the Core Data stack. It's the object you use to create and fetch managed objects, and to manage undo and redo operations. Within a given context, there is at most one managed object to represent any given record in a persistent store.

When should you save context in Core Data?

Only Save A Context That Has Changes hasChanges : true if you have inserted, deleted or updated the object (a combination of the following properties). isInserted : true when you insert the object into a context.

Can we have multiple managed object context in Core Data?

Most apps need just a single managed object context. The default configuration in most Core Data apps is a single managed object context associated with the main queue. Multiple managed object contexts make your apps harder to debug; it's not something you'd use in every app, in every situation.


1 Answers

The NSManagedObjectContext is the in-memory container of your applications object graph, just as the persistent store (XML, SQLite, etc.) usually represents the on disk container of your object graph.

There are some advantages to this approach:

  1. Faulting can be applied to a set of objects, or in the case of CoreData the entire object graph
  2. It's a convenient abstraction for forcing the application to batch it's I/O.
  3. It provides a single point of contact for efficiently performing operations over the entire object graph (NSFetchRequests, etc.)
  4. Undo can be applied to the object graph, not just individual objects.

It's also important to remember that CoreData is not an ORM framework, it's an object persistence framework. The primary responsibility of CoreData is to make accessing data stored in a persistent format on disk more efficient. However it doesn't attempt to emulate the functionality of relational databases.

To your point about concurrency, new concurrency models have been introduced in the upcoming release of Mac OSX. You can read more about that at developer.apple.com.

In the abstract though, the concurrency model chosen for a managed object context has more to do with the specifics of an individual application than the context pattern itself. Instances of NSManagedObjectContext should generally never be shared between threads.

In the same way that each thread requires it's own instance of NSAutoReleasePool, each thread should also have it's own MOC. That way, when the thread is done executing, it can commit it's changes to the store on disk and then release the context, freeing up all the memory consumed by objects processed on the thread.

This is a much more efficient paradigm than allowing a single context to continuously consume system resources during the lifecycle of a given application. Of course, this can be done by invoking -reset on the context as well, which will cause all of the NSManagedObject's in use by the context to be turned back in to faults.

like image 94
ImHuntingWabbits Avatar answered Sep 30 '22 10:09

ImHuntingWabbits