How to correctly manage the NSManagedObjectContext in each view controller?
I'm relative new with CoreData and I want to know if I'm doing the things right. First the documentation says:
"By convention, you get a context from a view controller. You must implement your application appropriately, though, to follow this pattern.
When you implement a view controller that integrates with Core Data, you can add an NSManagedObjectContext property.
When you create a view controller, you pass it the context it should use. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It's typically the responsibility of the application delegate to create a context to pass to the first view controller that's displayed."
https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/stack.html
so what I do is create a property for my NSManagedObjectContext:
MyViewController.H
@interface MyViewController : ViewController
{
NSManagedObjectContext *moc;
}
@property (nonatomic, retain) NSManagedObjectContext *moc;
@end
MyViewController.m
@implementation MyViewController
@synthesize moc=moc;
1.-And any place I want to do some change to the database I do this.
MainNexarAppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
self.moc = [[NSManagedObjectContext alloc] init];
self.moc.persistentStoreCoordinator = [appDelegate persistentStoreCoordinator];
/*code**/
[self.moc save:&error];
2-.And if I'm going to work in a different thread I have my custom method to create the NSManagedObjectContext with NSPrivateQueueConcurrencyType so it can be manage in a private queue:
//Myclass NSObject<br>
-(NSManagedObjectContext *)createManagedObjectContext{
MainNexarAppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSPersistentStoreCoordinator *coordinator = [appDelegate persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
//__managedObjectContext is my property from the .h file
//@property (readonly,strong,nonatomic) NSManagedObjectContext* managedObjectContext;
1.1. It's a valid approach use [UIApplication sharedApplication] to get the persistent NSPersistentStoreCoordinator form the appdelegate?
Any help will be appreciated :).
I am going to disagree with most of the answers here. It is NOT bad for #1. In fact, it is probably good practice in most cases to do so. Especially if you have different threads running stuff. It has greatly simplified my apps to create NSManagedObjectContexts whenever needed including per view controller. This is also recommended by the guys behind MagicalRecord (which is what I use to make use of Core Data in most cases). NSManagedObjectContext creation is not a high overhead call per the MR guys. I am not a CoreData expert by any stretch of the imagination, but I have had much better results in doing it this way, as recommended to me by the MagicalRecord guys.
I can only provide help for issue #1. The following is an example of what the Apple docs mean when they say pass the context to your view controllers. In this case, the app delegate is passing the context to the root view controller after the app delegate creates the context.
// in AppDelegate.m (using storyboard)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// let's assume that your MyViewController is the root view controller; grab a reference to the root view controller
MyViewController *rootViewController = (MyViewController *)self.window.rootViewController;
// initialize the Core Data stack...
rootViewController.moc = ... // pass the context to your view controller
return YES;
}
NSManagedObjectContext
for each controller. All you need is to have own context for each thread. So it depends on your logic. 1.1. Yes, it's not bad. In my apps I use a singleton class with shared NSPersistentStoreCoordinator
. And if I need to create new context, I use
self.context = [NSManagedObjectContext new];
self.context.persistentStoreCoordinator = [[SharedStorage sharedStorage] storeCoordinator];
A bit detailed code snippet here. Usually my view controllers which use NSManagedObjectContext
have table views, so I use NSFetchedResultsController
. And I use only one shared context for all this controllers.
Note 1: Some say it's a bad idea to have singletons.
Note 2: Don't forget that you need to synchronize all your contexts via save
and merge
methods.
上一篇: 指南针config.rb位置