如何加速核心数据迁移或其他解决方案

时间:2014-02-24 13:45:17

标签: ios iphone performance core-data database-migration

我在我的iOS应用程序中使用Coredata。它有大约20个表,我的应用程序使用数据库中的图像(图像编辑应用程序)。所以数据库数据是如此庞大和沉重。

有一天,我在一张桌子上添加了几列。它只是String列。当然我知道如何迁移和实现它,所以我添加了新的.xcdatamodel并更改了当前。当我在我的设备中测试时,我没有任何错误和冲突。所以我把它发布到iOS开发者中心,它可以宣布。最后,许多用户开始更新我的应用程序。

但有些用户表示“从未完成更新。” “更新需要50分钟。” ......等等 更新意味着迁移。我通过用户报告的进度确认了它。我不敢相信迁移需要50分钟!但也许这是真的。因为当我测试使用50个图像并保存到CoreData时,我的设备大约需要1分钟。我认为我们的客户使用300~500个图像和用户其他数据。对于iPhone4或iPhone4S,迁移需要很长时间......

所以我想知道如何加速这些用户的CoreData迁移。
现在我正在使用自动迁移,否则我可以选择手动迁移 我发现了一些技巧,并告诉工程师,并收集它,我推断手动迁移比自动迁移慢 我正在寻找其他并行解决方案。它将coredata导出到PC。 PC迁移而不是iPhone。并且iPhone导入迁移的数据。有谁知道这种方式可行吗?

最后,我提出了我的迁移代码。这很简单。

@try {
    // init application (Before application:didFinishLaunchingWithOptions:)
LOG(@"start migration");

    NSPersistentStoreCoordinator *migPersistent;

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:[[self class] sqliteFileInDocumentsUrlString]];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
    NSError *error = nil;
    migPersistent = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![migPersistent addPersistentStoreWithType:NSSQLiteStoreType
                                     configuration:nil
                                               URL:storeURL
                                           options:options
                                             error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        [migPersistent release];
        return NO;
    }

    [migPersistent release];
    LOG(@"finish migration");
}
@catch (NSException *exception) {
    .....
}
@finally {
    // Do Nothing
}

此外,此代码在MainThread上运行。
喜欢 ViewDidAppear(LoadingWindow) - > performSelector:withObject:afterDelay - >迁移。


感谢您收看此问题,对不起我的英语..



Editted 2014.02.25 21:11

我收到了跟踪文件并上传了以下网址 https://www.dropbox.com/sh/dmlf4j4z3vkj3p0/DrDBL_guYy

[测试流程](设备:iPodtouch 5th Gen iOS 7.0.6)
1.在先前版本中插入195KB(宽度:960,高度:1280)x 1000张图像 2.安装当前版本并运行迁移。它完成了大约11分钟。

那么为什么用户得到50分钟


Editted 2014.02.26 8:59

抱歉,上述网址错误。请检查此URL https://www.dropbox.com/s/8xaxwyfex7gyjdt/traceFolder.zip


Editted 2014.02.26 10:43

  

发生了什么 - [PapeDataManager migrate]?如果可以,请添加代码

这是上面的代码。这个方法得到184977x。

[migPersistent addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL
                                           options:options error:&error]


  

在[PapeDataManager repairImageNamePath]中发生了什么?

这种方法得到了160775x [self.managedObjectContext save:&error]

self.managedObjectContext是NSManagedObjectContext 保存似乎是沉重的过程。因为它是在迁移之后。

现在,我有一些问题。

(1)MainThread的运行时间摘要约为6分钟,但TimeProfiler的处理总时间为11分钟。为什么会出现这种差异?

(2)当我在迁移时按下主页按钮时,迁移过程将会死亡?我只是检查它。但如果你知道这件事。请告诉我。


Editted 2014.02.26 12:09

关于(2)。 我已经测试了50个图像迁移。
当我按下主页按钮30秒后,BackGround任务暂停。

所以喜欢这个流程 申请午餐 - >正在加载开始 - >迁移 - > (推送HomeButton并将应用程序发送到后台) - >迁移完成 - > BackGround流程已暂停 - > (推送应用程序图标并将应用程序发送到前台) - >保存 - >装载完成

我不知道为什么加载过程在后台应用时不会继续。也许我们的用户因长时间加载而生气的原因是这样的。

1 个答案:

答案 0 :(得分:1)

即使持久存储中的图像似乎比自动/轻量级迁移花费的时间长得多。

假设您现在已经构建了一个包含500个图像的测试用例来跟踪它;下一步是在发生迁移时针对应用程序运行工具,并查看花费的时间。如果时间确实在核心数据中(而不是某些UI事件正在进行中),那么请使用来自Instruments的跟踪编辑您的帖子。

很可能您的应用程序在迁移消耗时间之后立即尝试对数据执行某些操作。没有仪器痕迹很难分辨。

更新(来自追踪)

-[PapeDataManager migrate]发生了什么?如果可以,请添加代码

-[PapeDataManager repairImageNamePath]发生了什么?

-repairImageNamePath花费的时间最多,如果你能解决这个问题,你会看到性能的显着提升。

更新2

启用SQLite debug可让您了解所有时间内的情况。如果由于商店中的blob确实是大量的sql调用,那么你需要重构你的商店,可能需要手动迁移(不重,但从Core Data导出并重建文件)来解决这个问题。 p>