简体   繁体   English

iOS CoreData 批量插入?

[英]iOS CoreData batch insert?

In my iPhone application, i need to insert ~2000 records into Core Data before the user can use any features of the application.在我的 iPhone 应用程序中,我需要将 ~2000 条记录插入到 Core Data 中,然后用户才能使用该应用程序的任何功能。 I am loading the records into CoreData from a local JSON file.我正在将记录从本地 JSON 文件加载到 CoreData 中。 This process is taking a long time(2.5+ minutes), but only needs to happen once(or every ~10 application opens to get updated data).这个过程需要很长时间(2.5+ 分钟),但只需要发生一次(或每打开大约 10 个应用程序以获取更新的数据)。

Is there a batch insert for Core Data?核心数据有批量插入吗? How can i speed up this insert process?我怎样才能加快这个插入过程?

If i can't speed it up using Core Data, what are the other recommended options?如果我无法使用 Core Data 加快速度,还有哪些其他推荐选项?

Check out the Efficiently Importing Data chapter from the Core Data Programming Guide.查看 Core Data Programming Guide 中的Efficiently Importing Data一章。

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.我目前遇到和你一样的问题,只是我插入了 10000 个对象,大约需要 30 秒,这对我来说仍然很慢。 I'm doing a [managedObjectContext save] on every 1000 managed objects inserted into the context (in other words, my batch size is 1000).我正在对插入上下文的每 1000 个托管对象执行 [managedObjectContext save](换句话说,我的批处理大小为 1000)。 I've experimented with 30 different batch sizes (from 1 to 10000), and 1000 seems to be the optimum value in my case.我已经尝试了 30 种不同的批量大小(从 1 到 10000),在我的情况下,1000 似乎是最佳值。

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. @VladimirMitrovic 的回答当时很有帮助,因为我知道我不应该每次都保存上下文,但我也在寻找一些示例代码。

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()
    }
}

Objective-C目标-C

Version for @Suragch anwser @Suragch anwser 的版本

NSManagedObjectContext * MOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
MOC.persistentStoreCoordinator = YOURDB.persistentStoreCoordinator;
[MOC performBlock:^{ 
   // DO YOUR OPERATION
 }];

I like @Suragch 's answer very much.我非常喜欢@Suragch 的回答。 This is the Objective-C version for it.这是它的 Objective-C 版本。

    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];
        }
    }];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM