iOS CoreData batch insert?

后端 未结 4 1676
你的背包
你的背包 2020-12-01 03:34

In my iPhone application, i need to insert ~2000 records into Core Data before the user can use any features of the application. I am loading the records into CoreData from

相关标签:
4条回答
  • 2020-12-01 04:19

    Objective-C

    Version for @Suragch anwser

    NSManagedObjectContext * MOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    MOC.persistentStoreCoordinator = YOURDB.persistentStoreCoordinator;
    [MOC performBlock:^{ 
       // DO YOUR OPERATION
     }];
    
    0 讨论(0)
  • 2020-12-01 04:26

    Check out the Efficiently Importing Data chapter from the Core Data Programming Guide.

    I'm currently having the same problems as you, only I'm inserting 10000 objects and it takes around 30s, which is still slow for me. I'm doing a [managedObjectContext save] on every 1000 managed objects inserted into the context (in other words, my batch size is 1000). I've experimented with 30 different batch sizes (from 1 to 10000), and 1000 seems to be the optimum value in my case.

    0 讨论(0)
  • 2020-12-01 04:33

    I was looking for the answer to a similar question when I came across this one. @VladimirMitrovic's answer was helpful at the time for knowing that I shouldn't save the context every time, but I was also looking for some sample code.

    Now that I have it, I will provide the code below so that other people can see what it might look like to do a batch insert.

    // set up a managed object context just for the insert. This is in addition to the managed object context you may have in your App Delegate.
    let managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = (UIApplication.sharedApplication().delegate as! AppDelegate).persistentStoreCoordinator // or wherever your coordinator is
    
    managedObjectContext.performBlock { // runs asynchronously
    
        while(true) { // loop through each batch of inserts. Your implementation may vary.
    
            autoreleasepool { // auto release objects after the batch save
    
                let array: Array<MyManagedObject>? = getNextBatchOfObjects() // The MyManagedObject class is your entity class, probably named the same as MyEntity
                if array == nil { break } // there are no more objects to insert so stop looping through the batches
    
                // insert new entity object
                for item in array! {
                    let newEntityObject = NSEntityDescription.insertNewObjectForEntityForName("MyEntity", inManagedObjectContext: managedObjectContext) as! MyManagedObject
                    newObject.attribute1 = item.whatever
                    newObject.attribute2 = item.whoever
                    newObject.attribute3 = item.whenever
                }
            }
    
            // only save once per batch insert
            do {
                try managedObjectContext.save()
            } catch {
                print(error)
            }
    
            managedObjectContext.reset()
        }
    }
    
    0 讨论(0)
  • 2020-12-01 04:34

    I like @Suragch 's answer very much. This is the Objective-C version for it.

        NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
        managedObjectContext.persistentStoreCoordinator = [[UIApplication sharedApplication].delegate.persistentStoreCoordinator];
    
        [managedObjectContext performBlock:^{
            while (true) {
                @autoreleasepool {
                    // Code that creates autoreleased objects.
                    NSArray *batchObjects = [self getNextBatchOfObjects];
    
                    if (!batchObjects) {
                        break;
                    }
    
                    for (id item in batchObjects) {
                        MyEntity *newItem = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:managedObjectContext];
                        newObject.attribute1 = item.whatever;
                        newObject.attribute2 = item.whoever
                        newObject.attribute3 = item.whenever
                    }
                }
    
                // only save once per batch insert
                NSError *error = nil;
                [managedObjectContext save:&error];
                [managedObjectContext reset];
            }
        }];
    
    0 讨论(0)
提交回复
热议问题