【发布时间】:2014-02-24 13:45:17
【问题描述】:
我将 Coredata 用于我的 iOS 应用程序。它有大约 20 个表,我的应用程序使用数据库中的可能图像(图像编辑应用程序)。所以数据库数据如此庞大和沉重。
有一天,我在一张表中添加了几列。它只是字符串列。当然我知道如何迁移和实现它,所以我添加了新的 .xcdatamodel 并更改了当前的。当我在我的设备中测试时,我没有收到任何错误和冲突。所以我将它发布到iOS开发者中心,它可以被宣布。终于,很多用户开始更新我的应用了。
但有些用户说“从未完成更新”。 “更新需要 50 分钟。”等等...
更新意味着迁移。我通过用户报告的进度确认了这一点。我不敢相信迁移需要 50 分钟!但也许这是真的。因为当我测试使用 50 张图像并保存到 CoreData 时,我的设备大约需要 1 分钟。我认为我们的客户使用 300 ~ 500 张图像和用户其他数据。如果是 iPhone4 或 iPhone4S,迁移需要很长时间...
所以我想知道如何为这些用户加快 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 -> 迁移。
感谢您观看此问题,对不起,我的英语很糟糕..
编辑于 2014.02.25 21:11
我得到了跟踪文件并上传了以下 URL。
https://www.dropbox.com/sh/dmlf4j4z3vkj3p0/DrDBL_guYy
[测试流程](设备:iPodtouch 5th Gen iOS 7.0.6)
1. 在之前的版本中插入了 195KB(Width:960,Height:1280) x 1000 图片。
2. 安装当前版本并运行迁移。它完成了大约11分钟。
那么为什么用户得到 50 分钟???
编辑于 2014.02.26 8:59
抱歉,以上网址有误。请检查此网址。
https://www.dropbox.com/s/8xaxwyfex7gyjdt/traceFolder.zip
编辑于 2014.02.26 10:43
-[PapeDataManager 迁移] 中发生了什么?如果可以,请添加代码
上面的代码。这个方法得到了 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) 当我在迁移时按下主页按钮时,迁移过程会死机吗?我只是在检查它。但如果你知道这一点。请告诉我。
编辑于 2014.02.26 12:09
关于 (2)。
我已经测试了 50 个图像迁移。
当我按下主页按钮和 30 秒后,后台任务已暂停。
所以像这样的流程
应用程序午餐->加载开始->迁移->(按下HomeButton并将应用程序发送到后台)->迁移完成->后台进程暂停->(推送应用程序图标并将应用程序发送到前台)->保存->加载完成
我不知道为什么应用程序在后台时加载过程不会继续。也许我们的用户对加载时间长感到愤怒的原因就是这个。
【问题讨论】:
-
我知道这个问题,但没有完整的解决方案。需要这么长时间的原因是整个数据库被读入内存进行迁移。有手动迁移的可能性,您可以在其中微调迁移。请参阅 developer.apple.com/library/mac/documentation/cocoa/conceptual/… 标题为多次传递—处理大型数据集的部分
-
我建议将代码移到主线程之外,并允许用户在迁移过程中使用应用程序。
-
也许你应该把图像放在核心数据之外?
-
@Volker 这是不正确的。发生自动/轻量级迁移时,不会将整个数据库加载到内存中。这只发生在大量迁移时。
-
@Volker 如果您使用的是映射模型,那么您正在进行大量迁移。
标签: ios iphone performance core-data database-migration