Ios 核心数据:应用程序启动时添加持久存储超时

Ios 核心数据:应用程序启动时添加持久存储超时,ios,core-data,Ios,Core Data,我有一个在应用程序中创建持久存储的应用程序:didfishlaunchwithoptions。添加应用商店显然需要很长时间,这会导致iOS在应用程序完成启动之前终止应用程序。超时时的堆栈跟踪如下所示。有人知道如何防止这种情况发生吗 Exception Type: 00000020 Exception Codes: 0x000000008badf00d Highlighted Thread: 0 Application Specific Information: com.foo.bar fa

我有一个在
应用程序中创建持久存储的应用程序:didfishlaunchwithoptions
。添加应用商店显然需要很长时间,这会导致iOS在应用程序完成启动之前终止应用程序。超时时的堆栈跟踪如下所示。有人知道如何防止这种情况发生吗

Exception Type:  00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread:  0

Application Specific Information:
com.foo.bar failed to launch in time

Elapsed total CPU time (seconds): 23.490 (user 23.490, system 0.000), 78% CPU 
Elapsed application CPU time (seconds): 8.406, 28% CPU

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0:
0   libsystem_kernel.dylib          0x31b8939c pread + 20
1   libsqlite3.dylib                0x31ed95d0 unixRead
2   libsqlite3.dylib                0x31eec106 readDbPage
3   libsqlite3.dylib                0x31eeb2a2 sqlite3PagerAcquire
4   libsqlite3.dylib                0x31f04096 moveToChild
5   libsqlite3.dylib                0x31f052c6 sqlite3BtreeNext
6   libsqlite3.dylib                0x31f01490 sqlite3VdbeExec
7   libsqlite3.dylib                0x31efa48a sqlite3_step
8   CoreData                        0x364f8892 _execute
9   CoreData                        0x364f878c -[NSSQLiteConnection execute]
10  CoreData                        0x3658bd94 -[NSSQLConnection prepareAndExecuteSQLStatement:]
11  CoreData                        0x365dd4f2 -[_NSSQLiteStoreMigrator performMigration:]
12  CoreData                        0x365d70dc -[NSSQLiteInPlaceMigrationManager migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:]
13  CoreData                        0x36577428 -[NSMigrationManager migrateStoreFromURL:type:options:withMappingModel:toDestinationURL:destinationType:destinationOptions:error:]
14  CoreData                        0x365c8670 -[NSStoreMigrationPolicy(InternalMethods) migrateStoreAtURL:toURL:storeType:options:withManager:error:]
15  CoreData                        0x365c79c4 -[NSStoreMigrationPolicy migrateStoreAtURL:withManager:metadata:options:error:]
16  CoreData                        0x365c8ece -[NSStoreMigrationPolicy(InternalMethods) _gatherDataAndPerformMigration:]
17  CoreData                        0x364ec3b0 -[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:]

不良食品是一种常见的发射事故。您需要在主线程之外创建核心数据堆栈。过去我在这里和其他地方讨论过几次

您还可以查看Aplle的iCloud核心Datavidros,因为发布代码也将解决您的问题

请记住,您的应用程序需要能够在没有堆栈的情况下启动。对于现有的应用程序,这可能是一个重大变化

更新2 这一直被推荐,但不幸的是,直到最近它才开始显示在模板中

有几件事可能会导致添加持久性存储需要更长的时间:

  • 如果要将数据库从一个版本迁移到另一个版本;将存储添加到协调器时会发生迁移
  • 如果您将iCloud添加到应用程序中,则在首次发布时需要花费更长的时间
  • 如果核心数据确定需要对数据库进行维护,则可能需要比预期更长的时间
  • “正确”的答案是将存储添加到主线程之外的协调器

    快速/有效的解决方法是打开核心数据的sql日志记录,然后查看在启动过程中发生了什么。一旦您了解造成延迟的原因,您就可以解决它。如果是迁移,那么正确的答案可能是唯一的答案

    更新3
  • 在仪器中对此进行配置。这会告诉你慢度在哪里
  • 什么是
    dataToMigrate=[self-fetchSomeDataFromDatabase]做什么

  • 看看你的时间档案,它会告诉你什么是慢的。从instruments向我发送时间配置文件,我也会查看它。

    不良食品是常见的发射崩溃。您需要在主线程之外创建核心数据堆栈。过去我在这里和其他地方讨论过几次

    您还可以查看Aplle的iCloud核心Datavidros,因为发布代码也将解决您的问题

    请记住,您的应用程序需要能够在没有堆栈的情况下启动。对于现有的应用程序,这可能是一个重大变化

    更新2 这一直被推荐,但不幸的是,直到最近它才开始显示在模板中

    有几件事可能会导致添加持久性存储需要更长的时间:

  • 如果要将数据库从一个版本迁移到另一个版本;将存储添加到协调器时会发生迁移
  • 如果您将iCloud添加到应用程序中,则在首次发布时需要花费更长的时间
  • 如果核心数据确定需要对数据库进行维护,则可能需要比预期更长的时间
  • “正确”的答案是将存储添加到主线程之外的协调器

    快速/有效的解决方法是打开核心数据的sql日志记录,然后查看在启动过程中发生了什么。一旦您了解造成延迟的原因,您就可以解决它。如果是迁移,那么正确的答案可能是唯一的答案

    更新3
  • 在仪器中对此进行配置。这会告诉你慢度在哪里
  • 什么是
    dataToMigrate=[self-fetchSomeDataFromDatabase]做什么
  • 看看你的时间档案,它会告诉你什么是慢的。从instruments向我发送时间配置文件,我也会查看它。

    代码很简单:

        dispatch_async(DISPATCH_QUEUE_PRIORITY_HIGH, ^{
            [self setupCoreDataStack]; //TODO
        })
    
    但正如马库斯所说,确保你的应用程序能够处理启动时没有准备好CoreData(现在是异步的)。。例如,您可以设置一个启动屏幕!?/不使用db代码的基本菜单很简单:

        dispatch_async(DISPATCH_QUEUE_PRIORITY_HIGH, ^{
            [self setupCoreDataStack]; //TODO
        })
    

    但正如马库斯所说,确保你的应用程序能够处理启动时没有准备好CoreData(现在是异步的)。。例如,您可以设置一个启动屏幕!?/不使用db的基本菜单很有趣。我不认为这是必要的,因为当您创建一个新的Xcode项目时,生成的模板会在主线程上添加持久存储?这是我们看到的一个新问题,我不确定会有什么变化。除了重新编写整个应用程序使其不依赖于商店的可用性之外,还有没有其他侵入性较小的方法来缓解这种启动崩溃?非常感谢,这真的很有帮助。我仍然不清楚到底是什么导致了这一切。我不是迁移数据库或使用iCloud,我只是删除一个数据库(如果它存在),然后再创建一个新的数据库。代码是这样的:谢谢你,马库斯!我将尝试分析,但不确定我会有多少运气,因为我真的无法重现这个问题。
    dataToMigrate=[self-fetchSomeDataFromDatabase]
    ;只是简单地获取一些用户数据,以防止用户在建立新存储后重新登录。我想知道当我没有真正尝试执行迁移时,是否会设置
    nsmigratePersistentStoresAutomaticalyOption
    nsinFermappingModelAutomaticalyOption
    ?分析显示,从一个MOM迁移到另一个MOM需要很长时间。我不知道为什么,因为这是一次“轻度”迁移。我正在考虑两种不同的方法:1)保留迁移,但将其移动到后台线程。这让我有点担心,因为它不需要太长时间,我们不需要迁移,只需要从旧存储中提取一点数据。2) 将堆栈创建移动到后台线程上,但也可以通过传递
    nsignorescistentstore来避免迁移