ZZ says multithreading core Data for iOS

Source: Internet
Author: User

Core data is an important part of iOS, which can be understood as an ORM implementation based on SQLite (or, of course, other storage, such as In-memory, which is only common to sqlite), so there are characteristics of relational databases and no need to write SQL. By the way, the official statement is that using core data can reduce the amount of code by 50%-70%, but believe that the people who used it should understand that core data is cumbersome to use, which is why there are a number of third-party libraries to replace/two-pack Core data.

A slightly more complex application may have the possibility of processing multiple copies of data simultaneously, which requires multithreading core data. Prior to IOS 5, the official recommendation was to use "thread confinement", where each thread used a separate MOC (managed object context) and then shared a PSC (persistent store coordinator). While passing data between threads, pass Objectid, not object, because the former is thread-safe and the latter is not.

If the cud (Create, update, delete) operation is performed on the PSC in a thread, how does the other thread perceive it? This is done by listening to events. For example, the "nsmanagedobjectcontextdidsavenotification" event is monitored in thread A, and if the cud operation is performed in threads B, thread A can perceive and trigger the action of the response, although it can be noti UserInfo to get managed objects, but because they are associated to another MOC, they cannot be manipulated directly, and the workaround is to call the "mergechangesfromcontextdidsavenotification:" method.

In a picture, this is basically the case:

-(void)_setupcoredatastack{Setup managed Object ModelNsurl*Modelurl=[[NSBundleMainbundle]Urlforresource:@ "Database"Withextension:@ "MOMD"];_managedobjectmodel=[[NsmanagedobjectmodelAlloc]Initwithcontentsofurl:Modelurl];Setup Persistent Store CoordinatorNsurl*Storeurl=[NsurlFileurlwithpath:[[NSStringCachespath]stringByAppendingPathComponent:@ "Database.db"]];Nserror*Error=Nil;_persistentstorecoordinator=[[NspersistentstorecoordinatorAlloc]Initwithmanagedobjectmodel:_managedobjectmodel];If(![_persistentstorecoordinatorAddpersistentstorewithtype:NssqlitestoretypeConfiguration:NilUrl:StoreurlOptions:NilError:&Amp;Error]){Handle error}Create MOC_managedobjectcontext=[[NsmanagedobjectcontextAlloc]Init; [_managedobjectcontext setpersistentstorecoordinator :_persistentstorecoordinator//Subscribe to change notifications [[nsnotificationcenter defaultcenter addobserver:self selector: @selector  (_ Mocdidsavenotification:) name: Nsmanagedobjectcontextdidsavenotification object:nil ;                /span>               

Then look at notification Handler, the main role is to merge new changes.

-(void)_mocdidsavenotification:(Nsnotification*)Notification{Nsmanagedobjectcontext*savedcontext = [notification  Object; //ignore change notifications for the main MOC if  (_ Managedobjectcontext == savedcontext { return} dispatch_sync (dispatch_get_main_queue  (), ^{[_managedobjectcontext span class= "n" >mergechangesfromcontextdidsavenotification:notification ; );                /span>                

This approach is a bit cumbersome to implement and maintain, so there's a more convenient and flexible implementation in iOS 5, which is "nested moc".

[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

You can see that Concurrencytype can be selected at initialization, and there are 3 options:

Nsconfinementconcurrencytype

This is the default item, each thread is a separate context, primarily to be compatible with the previous design.

Nsprivatequeueconcurrencytype

Create a private queue (using GCD) so that the main thread is not blocked.

Nsmainqueueconcurrencytype

Creating a main queue, using the main thread, will block.

Another important change is that the MOC can specify the parent. With the parent, the cud action bubbles to the parent. A parent can have more than one child. The parent can also have a parent.

Because the UI-related data must be fetched on the main thread while avoiding the I/O operations of the database blocking the main thread, the following model is available:

One of my confusion about this realization is that the child cannot know the change of the parent, that is, if Nsfetchedresultscontroller binds the main MOC, when background Write MOC save, Why would nsfetchedresultscontroller know? Ask for advice.

This is a little bit simpler and clearer than "thread confinement". However, it is recommended to use Magicalrecord, because it is easier to implement, and then write an article when you are free.

Wrote a demo using this model, with TableView and Nsfetchedresultscontroller, interested can look under: Https://github.com/limboy/coredata-with-tableview

2013/06/17 Update

The previous confusion has been eliminated, regardless of the NSFetchedResultsController PSC, as long as the bound MOC has an save action, NSFetchedResultsController it will be notified, regardless of whether the operation has been save written to the persistence layer.

ZZ says multithreading core Data for iOS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.