Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>UIManagedDocument</code> is used to sync data (typically files) to iCloud. It is only tangentially related to Core Data.</p> <p>Core Data setup is typically done in the <code>AppDelegate</code> so there is nothing wrong with what you are doing there. In fact, if you create a new project using Core Data that is how the Xcode template will do it.</p> <p>You usually do not need to pass your <code>ManagedObjectContext</code> around from viewcontroller to viewcontroller. It is better to create a singleton Data Access layer which can provide context anywhere in your app. There are some cases where you might want to have a private MOC for a viewcontroller, but not very often. </p> <p>Here's some code to create a singleton DataAccessLayer:</p> <p>DataAccessLayer.h</p> <pre><code>@interface DataAccessLayer : NSObject //Saves the Data Model onto the DB - (void)saveContext; //DataAccessLayer singleton instance shared across application + (id) sharedInstance; + (void)disposeInstance; // Returns the managed object context for the application. // If the context doesn't already exist, it is created and bound // to the persistent store coordinator for the application. + (NSManagedObjectContext *)context; @end </code></pre> <p>DataAccessLayer.m</p> <pre><code>#import "DataAccessLayer.h" //static instance for singleton implementation static DataAccessLayer __strong *manager = nil; //Private instance methods/properties @interface DataAccessLayer () // Returns the managed object context for the application. // If the context doesn't already exist, it is created and // bound to the persistent store coordinator for the application. @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; // Returns the managed object model for the application. // If the model doesn't already exist, it is created from the application's model. @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; // Returns the persistent store coordinator for the application. // If the coordinator doesn't already exist, it is created and the application's // store added to it. @property (readonly,strong,nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; // Returns the URL to the application's Documents directory. - (NSURL *)applicationDocumentsDirectory; @end @implementation DataAccessLayer @synthesize managedObjectContext = __managedObjectContext; @synthesize managedObjectModel = __managedObjectModel; @synthesize persistentStoreCoordinator = __persistentStoreCoordinator; //DataAccessLayer singleton instance shared across application + (id)sharedInstance { @synchronized(self) { if (manager == nil) manager = [[self alloc] init]; } return manager; } + (void)disposeInstance { @synchronized(self) { manager = nil; } } +(NSManagedObjectContext *)context { return [[DataAccessLayer sharedInstance] managedObjectContext]; } //Saves the Data Model onto the DB - (void)saveContext { NSError *error = nil; NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { if ([managedObjectContext hasChanges] &amp;&amp; ![managedObjectContext save:&amp;error]) { //Need to come up with a better error management here. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } // Returns the managed object context for the application. // If the context doesn't already exist, it is created and // bound to the persistent store coordinator for the application. - (NSManagedObjectContext *)managedObjectContext { if (__managedObjectContext != nil) return __managedObjectContext; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { __managedObjectContext = [[NSManagedObjectContext alloc] init]; [__managedObjectContext setPersistentStoreCoordinator:coordinator]; } return __managedObjectContext; } // Returns the managed object model for the application. // If the model doesn't already exist, it is created from the // application's model. - (NSManagedObjectModel *)managedObjectModel { if (__managedObjectModel != nil) return __managedObjectModel; NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return __managedObjectModel; } // Returns the persistent store coordinator for the application. // If the coordinator doesn't already exist, it is created and the // application's store added to it. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (__persistentStoreCoordinator != nil) return __persistentStoreCoordinator; NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyData.sqlite"]; NSError *error = nil; __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&amp;error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return __persistentStoreCoordinator; } // Returns the URL to the application's Documents directory. - (NSURL *)applicationDocumentsDirectory { return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } @end </code></pre> <p>Any time you need context, you can grab it using:</p> <pre><code>NSManagedObjectContext *context = [DataAccessLayer context]; </code></pre> <p>This design generally works well. <code>NSManagedObjectContext</code> is a very lightweight object, so there isn't a real performance penalty keeping it around. However, if you need to do Core Data stuff on other threads, the design needs to change a bit. From <a href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html" rel="nofollow">Apple's docs</a>:</p> <blockquote> <p>You must create the managed context on the thread on which it will be used. If you use NSOperation, note that its init method is invoked on the same thread as the caller. You must not, therefore, create a managed object context for the queue in the queue’s init method, otherwise it is associated with the caller’s thread. Instead, you should create the context in main (for a serial queue) or start (for a concurrent queue).</p> <p>Using thread confinement, you should not pass managed objects or managed object contexts between threads. To “pass” a managed object from one context another across thread boundaries, you either:</p> <ul> <li>Pass its object ID (objectID) and use objectWithID: or existingObjectWithID:error: on the receiving managed object context. The corresponding managed objects must have been saved—you cannot pass the ID of a newly-inserted managed object to another context.</li> <li>Execute a fetch on the receiving context.</li> </ul> </blockquote>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload