I need to populate my map with annotations. Each annotation has corresponding Place resource that is being fetched from remote server. Each Place has associated Category - it is fetched from the server too as a separate resource.
Let's assume that to populate a given region I need to fetch 100 places, each belonging to the one of 20 categories (actually there are much more of them).
I use AFNetworking to fetch the both of resources. I try to cache both places and categories for offline use, so before the annotations are displayed on map, I write fetched resources to the Core Data tables.
Each place retrieves its associated category resource by demand and I need to write both a place in the 'places' table, and category in the 'categories' table.
Because of fetching is being done asynchronously, when writing particular category to table I can't know if maybe another place "thread" attempts to write the same associated category to 'categories' table.
So, the question is: what is the pattern for working with Core Data tables, when they need to be populated with information retrieved asynchronously? Specifically how any given thread which is going to write a category could know that there is already one trying to do that?
UPDATE 1: My current problem is that currently I am having the duplication of categories. My guess is that obviously each category which attempts to be written is not aware about the parallel write of the same category.
UPDATE 2: The most simple description of my case is the following:
I create a new Category entity with some fields in one thread and in the meantime in another thread I create exactly the same Category entity with the same fields aiming to be the same Category object like the first thread has.
One thread wins calling [managedObjectContext save:&error], but then before the actual record is appeared in the PersistentStore, the second does call the save too. The question is: how to prevent the duplication of records in 'categories' table?
UPDATE 3: I am considering both variants of using managed object contexts: 1) reusing one shared moc instance by all threads 2) instantiate a new moc on each thread
Thanks!
The "official" answer is going to be something about using an NSOperationQueue
and/or taking manual steps to ensure that all your accesses to the NSManagedObjectContext
occur on the same thread that created the context. There are a number of references and tutorials that you can follow to implement this approach.
As an alternative, there's a thread-safe Core Data extension on github that will do this for you. If you use it, it will automatically synchronize your database operations so that you don't have to worry about whether or not another thread is doing something with the context. You can just insert things as they come in, and the framework will ensure that your operations are translated into something that won't make Core Data explode.
Full disclosure: I built the github project.
来源:https://stackoverflow.com/questions/12790923/get-a-number-of-resources-asynchronously-and-asynchronously-save-them-to-a-dat