如何加快使用Core Data将新对象插入实体的速度

时间:2011-09-07 14:23:15

标签: iphone objective-c ios core-data

这是我的代码,它采用了一些JSON数据并将其插入到Core Data会议室实体中:

for (NSDictionary *room in rooms)
    {
        NSDictionary *thisroom = [room objectForKey:@"room"];
        NSString *roomidstring = [thisroom objectForKey:@"roomid"];
        int roomid = [roomidstring intValue];
        NSString *roomname = [thisroom objectForKey:@"roomname"];
        NSString *buildingidstring = [thisroom objectForKey:@"buildingid"];
        int buildingid = [buildingidstring intValue];

        // import into database
        NSManagedObject *roomInfo = [NSEntityDescription insertNewObjectForEntityForName:@"room" inManagedObjectContext:context];
        [roomInfo setValue:[NSNumber numberWithInteger:roomid] forKey:@"roomid"];
        [roomInfo setValue:roomname forKey:@"roomname"];
        [roomInfo setValue:[NSNumber numberWithInteger:buildingid] forKey:@"buildingid"];
         if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
    }

插入约900个物体时速度极慢。有没有办法让它更有效率和/或加快速度?

谢谢!

4 个答案:

答案 0 :(得分:8)

是的,在完成循环之前不要保存,或者如果内存有问题则分批保存。保存操作非常昂贵,因此您应该避免经常在像这样的紧密循环中保存。

for (NSDictionary *room in rooms)
{
    NSDictionary *thisroom = [room objectForKey:@"room"];
    NSString *roomidstring = [thisroom objectForKey:@"roomid"];
    int roomid = [roomidstring intValue];
    NSString *roomname = [thisroom objectForKey:@"roomname"];
    NSString *buildingidstring = [thisroom objectForKey:@"buildingid"];
    int buildingid = [buildingidstring intValue];

    // import into database
    NSManagedObject *roomInfo = [NSEntityDescription insertNewObjectForEntityForName:@"room" inManagedObjectContext:context];
    [roomInfo setValue:[NSNumber numberWithInteger:roomid] forKey:@"roomid"];
    [roomInfo setValue:roomname forKey:@"roomname"];
    [roomInfo setValue:[NSNumber numberWithInteger:buildingid] forKey:@"buildingid"];
}


if (![context save:&error]) {
     NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}

答案 1 :(得分:1)

如何将[context save]调用移出循环并在一次操作中保存所有这些调用?看起来每次进行保存都会让事情变得更慢。

答案 2 :(得分:0)

导入一次,将存储文件复制到文档目录,更新持久存储协调器代码以从新位置加载所述文件。

答案 3 :(得分:0)

另外(对于Joe的回答),您还可以通过在另一个线程上保存来加快节省时间(NSPrivateQueueConcurrencyType):

- (void)openDataBase {
    // Set up _persistentStoreCoordinator accordingly.

    privateWriterContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [privateWriterContext setPersistentStoreCoordinator:_persistentStoreCoordinator];

    context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    context.parentContext = _privateWriterContext;
}

- (void)save
{
    [context performBlock:^{
        NSError *error;
        if (![context save:&error]) { // This will forward save to the parent, which is privateWriterContext.
            NSLog(@"Error saving main DB: %@, %@", error, [error userInfo]);
            NSAssert(false, nil);
        }
        [privateWriterContext performBlock:^{
            NSError *error;
            if (![privateWriterContext save:&error]) {
                NSLog(@"Error saving writer DB: %@, %@", error, [error userInfo]);
                NSAssert(false, nil);
            }
        }];
    }];
}