Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I work on an app that regularly has to process 100K inserts, deletes, and updates with Core Data. If it is choking on 5K inserts, there is some optimization to be done. </p> <p>Firstly, create some NSOperation subclass for processing the data. Override its -main method to do the processing. This method is, however, not guaranteed to run on the main thread. Indeed, its purpose is to avoid executing costly code on the main thread which would affect the user experience by making it freeze up grossly. So within the -main method, you need to create another managed object context which is the child of your main thread's managed object context.</p> <pre><code>- (void)main { NSManagedObjectContext *ctx = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [ctx setPersistentStoreCoordinator:mainManagedObjectContext.persistentStoreCoordinator]; [ctx setUndoManager:nil]; // Do your insertions here! NSError *error = nil; [ctx save:&amp;error]; } </code></pre> <p>Given your circumstances, I don't believe you need an undo manager. Having one will incur a performance penalty because Core Data is tracking your changes. </p> <p>Use THIS context to perform all of your CRUD actions in the -main method, then save that managed object context. Whatever owns your main thread's managed object context must register to respond to the NSNotification named NSManagedObjectContextDidSaveNotification. Register like so:</p> <pre><code>[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mocDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil]; </code></pre> <p>Then define that selector:</p> <pre><code>- (void)mocDidSaveNotification:(NSNotification *)notification { NSManagedObjectContext *ctx = [notification object]; if (ctx == mainManagedObjectContext) return; [mainManagedObjectContext mergeChangesFromContextDidSaveNotification:notification]; } </code></pre> <p>When all of this comes together, it will allow you to perform long-running operations on background threads without blocking the UI thread. There are several variations of this architecture, but the central theme is this: processing on BG thread, merge on main thread, update your UI. Some other things to keep in mind: (1) keep an autorelease pool around during your processing and drain it every so often to keep your memory consumption down. In our case, we do it every 1000 objects. Adjust for your needs, but keep in mind that draining can be expensive depending on the amount of memory required per object, so you don't want to do it too often. (2) try to pare your data down to the absolute minimum that you need to have a functional app. By reducing the amount of data to parse, you reduce the amount of time required to save it. (3) by using this multithreaded approach, you can concurrently process your data. So create 3-4 instances of your NSOperation subclass, each of which processes only a portion of the data so that they all run concurrently, resulting in a smaller amount of real time consumed for parsing the data set.</p>
    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. This table or related slice is empty.
    1. This table or related slice is empty.
    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