如何在CoreData中正确添加大数据集?

时间:2013-04-03 06:55:10

标签: ios objective-c database core-data

我有一个巨大的NSArray(4.000.000个对象),我想保存到Core Data中。 因为我使用ARC并且自动释放池可能变得太大,所以我将进程划分为多个循环(因此自动释放池可以有机会自行消耗)。

在下面的代码中,我使用管理器(clMan)从数组(区域)内的字典中添加项目。字典包含两个字符串字段,这些字段被解析为标量整数。

将数据分区为多个循环的代码

int loopSize = 50000;
int loops = 0;
int totalRepetitions = regions.count;
loops = totalRepetitions / loopSize;
int remaining = totalRepetitions % loopSize;


loops += 1;


for (int i = 0; i < loops; i++) {

    int k = 0;
    if (i == 0) k = 1;

    if (i == (loops - 1))
    {
            // Last loop

            for (long j = i * loopSize + k; j < i * loopSize + remaining; j++) {
                [clMan addItemWithData:[regions objectAtIndex:j]];
            }
            [clMan saveContext];
            break;

    }

    // Complete loops before the last one
        for (long j = i * loopSize + k; j < (i + 1) * loopSize; j++) {
            [clMan addItemWithData:[regions objectAtIndex:j]];
        }
        [clMan saveContext];
        NSLog(@"Records added : %d", i * loopSize);

}
NSLog(@"Finished adding into core data");

将数据添加到核心数据的代码:

-(void)addItemWithData:(NSDictionary *)data
{

    MyRegion *region = [NSEntityDescription
                                              insertNewObjectForEntityForName:@"MyRegion"
                                              inManagedObjectContext:self.context];


    region.index = [((NSString *)[data objectForKey:REGION_INDEX]) intValue];
    region.id = [((NSString *)[data objectForKey:REGION_ID]) intValue];

} 

程序在达到1 500 000索引时崩溃。由于解析问题/逻辑,似乎没有发生崩溃。

有人能告诉我,我的逻辑是否错误或者在CoreData中添加这些数据的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

在每次循环之后,尝试调用NSManagedObjectContext.reset以“忘记”MOC中的本地副本。否则这些可能无法清除并导致问题。

iCloud上的WWDC 2012代码示例有一个名为seedStore的方法,他们将本地核心数据SQL数据库迁移到iCloud - 使用批量大小为5000的记录,并在那里明确指出:

if (0 == (i % batchSize)) {
    success = [moc save:&localError];
    if (success) {
        /*
           Reset the managed object context to free the memory for the inserted objects
           The faulting array used for the fetch request will automatically free
           objects with each batch, but inserted objects remain in the managed
           object context for the lifecycle of the context
         */
        [moc reset];
    } else {
        NSLog(@"Error saving during seed: %@", localError);
        break;
    }
}

(此处i是批次的当前索引,因此如果我们开始新批次则为i % batchSize == 0