iPhone应用程序启动时间和Core Data迁移

seh*_*ugg 11 iphone cocoa core-data

我有一个Core Data应用程序,我打算用新架构更新.轻量级迁移似乎有效,但需要时间与数据库中的数据量成比例.这发生在didFinishLaunchingWithOptions应用程序的阶段.

我想避免<app> failed to launch in time问题,所以我假设我无法在didFinishLaunchingWithOptions方法中保留迁移.

我假设最好的方法是在后台线程中执行迁移.我还假设我需要推迟加载主ViewController,直到加载完成,以避免使用managedObjectContext直到初始化完成.

这是否有意义,是否有这种初始化的示例代码(可能在Apple示例项目中)?

Mar*_*rra 13

您不能将迁移放入a中,NSOperation因为它需要在主线程上运行.您需要做的是在-applicationDidFinishLaunching:不触及Core Data堆栈的情况下退出方法.如果您可以快速完成该方法(并且运行循环周期),那么您的应用程序将不会被终止,只要用户愿意完成您的迁移,您就可以使用该应用程序.

请参阅我的答案:如何从Core Data自动轻量级迁移切换到手动?

2010年5月19日更新

澄清我对此的立场.它本来就可能做任何事情.但是,在后台线程上进行迁移是个坏主意.很难保证在迁移过程中堆栈永远不会被触及以及其他一些特定于线程的复杂问题.

可以做到,但它涉及高风险,这是完全没有必要的.可以并且应该使用主线程来执行主Core Data堆栈的迁移.很容易建立一个模态对话框让用户知道正在进行迁移,然后在主线程上执行迁移.

如果您的迁移过程需要花费大量时间,那么强烈建议您使用映射模型从自动迁移切换到手动迁移,以便您可以:

  • 如果需要,可以轻松退出迁移.
  • 如果用户退出您的应用程序,则以块的形式执行迁移.
  • 为用户提供有关迁移距离和完成时间的可靠反馈.

2015年12月15日更新

自从最初回答以来,已经发生了很多变化.

现在迁移答案是解雇他们在后台队列(通过dispatch_async对中NSPersistentStoreCoordinatoraddStore...调用).

这也意味着您需要确保您的UI可以处理持久层是空的/在未知的时间段内不可用.如何做到这一点取决于您的应用程序.

例如,您可以拥有一个临时UI,在持久层执行迁移时显示跳舞的猫.用户体验取决于您.

但是,您希望让用户在迁移过程中创建数据.这将使以后很难合并(如果有的话).


ohh*_*rob 7

对不起马库斯,我不得不恭敬地不以为然.您可以在后台迁移.

我的迁移在后台线程上运行.在慢速设备上可能需要10秒以上,因此我在后台线程上启动它并使用特定的模态视图控制器来显示进度.

这样做的方法是将正常的加载顺序分为两个阶段.

阶段1) 执行在启动时通常不需要托管对象的所有操作.此阶段的结束由检查确定,以确定是否需要迁移.

阶段2) 执行在启动时通常发生的所有需要​​托管对象的事情.当不需要迁移时,此阶段是阶段1)的立即延续.

这样,无论迁移处理的持续时间如何,您的应用都会完成启动.

为了成功执行长迁移,我使用模态视图控制器向用户显示迁移进度的反馈.然后我在后台线程中开始迁移,而模态视图控制器使用KVO更新它的进度条.

在迁移结束时,它关闭整个核心数据"堆栈",并且对主线程的回调将关闭模态并继续到阶段2).

这整个过程完美无瑕,尽管我仍然有一个开放的问题,即自动轻量级迁移的方式揭示了它的进展,就像手动迁移一样.

  • 我会把它放在专家级设计上.尝试在后台线程上执行此操作非常危险,并且非常容易搞砸.对于那些阅读这个解决方案的人,我不建议****全部**.您最好放置完全相同的模态视图,然后在主线程上处理迁移.搞砸用户数据的可能性要小得多.因此,我建议在主线程上进行所有迁移. (6认同)