Sunday, 15 June 2014

iphone - Core Data: UIManagedDocument or AppDelegate to setup core data stack? -



iphone - Core Data: UIManagedDocument or AppDelegate to setup core data stack? -

i little confused setup core info stack. in appdelegate or using shared instance of uimanageddocument, described here?: http://adevelopingstory.com/blog/2012/03/core-data-with-a-single-shared-uimanageddocument.html

right have core info stack setup in appdelegate , passing moc around between viewcontrollers. improve migrate uimanageddocument , create shared instance, don't have pass moc around time? , because newer?

uimanageddocument used sync info (typically files) icloud. tangentially related core data.

core info setup typically done in appdelegate there nil wrong doing there. in fact, if create new project using core info how xcode template it.

you not need pass managedobjectcontext around viewcontroller viewcontroller. improve create singleton info access layer can provide context anywhere in app. there cases might want have private moc viewcontroller, not often.

here's code create singleton dataaccesslayer:

dataaccesslayer.h

@interface dataaccesslayer : nsobject //saves info model onto db - (void)savecontext; //dataaccesslayer singleton instance shared across application + (id) sharedinstance; + (void)disposeinstance; // returns managed object context application. // if context doesn't exist, created , bound // persistent store coordinator application. + (nsmanagedobjectcontext *)context; @end

dataaccesslayer.m

#import "dataaccesslayer.h" //static instance singleton implementation static dataaccesslayer __strong *manager = nil; //private instance methods/properties @interface dataaccesslayer () // returns managed object context application. // if context doesn't exist, created , // bound persistent store coordinator application. @property (readonly, strong, nonatomic) nsmanagedobjectcontext *managedobjectcontext; // returns managed object model application. // if model doesn't exist, created application's model. @property (readonly, strong, nonatomic) nsmanagedobjectmodel *managedobjectmodel; // returns persistent store coordinator application. // if coordinator doesn't exist, created , application's // store added it. @property (readonly,strong,nonatomic) nspersistentstorecoordinator *persistentstorecoordinator; // returns url 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]; } homecoming manager; } + (void)disposeinstance { @synchronized(self) { manager = nil; } } +(nsmanagedobjectcontext *)context { homecoming [[dataaccesslayer sharedinstance] managedobjectcontext]; } //saves info model onto db - (void)savecontext { nserror *error = nil; nsmanagedobjectcontext *managedobjectcontext = self.managedobjectcontext; if (managedobjectcontext != nil) { if ([managedobjectcontext haschanges] && ![managedobjectcontext save:&error]) { //need come improve error management here. nslog(@"unresolved error %@, %@", error, [error userinfo]); abort(); } } } // returns managed object context application. // if context doesn't exist, created , // bound persistent store coordinator application. - (nsmanagedobjectcontext *)managedobjectcontext { if (__managedobjectcontext != nil) homecoming __managedobjectcontext; nspersistentstorecoordinator *coordinator = [self persistentstorecoordinator]; if (coordinator != nil) { __managedobjectcontext = [[nsmanagedobjectcontext alloc] init]; [__managedobjectcontext setpersistentstorecoordinator:coordinator]; } homecoming __managedobjectcontext; } // returns managed object model application. // if model doesn't exist, created // application's model. - (nsmanagedobjectmodel *)managedobjectmodel { if (__managedobjectmodel != nil) homecoming __managedobjectmodel; nsurl *modelurl = [[nsbundle mainbundle] urlforresource:@"model" withextension:@"momd"]; __managedobjectmodel = [[nsmanagedobjectmodel alloc] initwithcontentsofurl:modelurl]; homecoming __managedobjectmodel; } // returns persistent store coordinator application. // if coordinator doesn't exist, created , // application's store added it. - (nspersistentstorecoordinator *)persistentstorecoordinator { if (__persistentstorecoordinator != nil) homecoming __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:&error]) { nslog(@"unresolved error %@, %@", error, [error userinfo]); abort(); } homecoming __persistentstorecoordinator; } // returns url application's documents directory. - (nsurl *)applicationdocumentsdirectory { homecoming [[[nsfilemanager defaultmanager] urlsfordirectory:nsdocumentdirectory indomains:nsuserdomainmask] lastobject]; } @end

any time need context, can grab using:

nsmanagedobjectcontext *context = [dataaccesslayer context];

this design works well. nsmanagedobjectcontext lightweight object, there isn't real performance penalty keeping around. however, if need core info stuff on other threads, design needs alter bit. apple's docs:

you must create managed context on thread on used. if utilize nsoperation, note init method invoked on same thread caller. must not, therefore, create managed object context queue in queue’s init method, otherwise associated caller’s thread. instead, should create context in main (for serial queue) or start (for concurrent queue).

using thread confinement, should not pass managed objects or managed object contexts between threads. “pass” managed object 1 context across thread boundaries, either:

pass object id (objectid) , utilize objectwithid: or existingobjectwithid:error: on receiving managed object context. corresponding managed objects must have been saved—you cannot pass id of newly-inserted managed object context. execute fetch on receiving context.

iphone ios objective-c core-data sdk

No comments:

Post a Comment