【问题标题】:Batch delete request crashes app批量删除请求使应用程序崩溃
【发布时间】:2016-08-25 22:25:12
【问题描述】:

我有一个 InMemory Store Coordinator 声明如下:

lazy var ramStoreCoordinator: NSPersistentStoreCoordinator = {
    // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStoreWithType(NSInMemoryStoreType, configuration: nil, URL: nil, options: nil)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }

    return coordinator
}()

以及关联的 ManagedObjectContext:

lazy var ramManagedObjectContext: NSManagedObjectContext = {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
    let coordinator = self.ramStoreCoordinator
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator
    managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    return managedObjectContext
}()

我正在尝试执行这样的获取请求:

    let fetchRequest = NSFetchRequest(entityName: "Post")
    let batchDelete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    do {
        // Execute Batch Request
        try ramManagedObjectContext.executeRequest(batchDelete)
    } catch {
        let updateError = error as NSError
        print("\(updateError), \(updateError.userInfo)")
    }

行:

try ramManagedObjectContext.executeRequest(batchDelete)

使用以下输出使应用程序崩溃:

2016-04-30 23:47:40.271 Secret[2368:1047869] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“未知命令类型(实体:EntityName;谓词:((null) ); sortDescriptors: ((null)); 类型: NSManagedObjectIDResultType; ) >' * 首先抛出调用栈: (0x18145ae38 0x180abff80 0x1833710b0 0x18338991c 0x183391d64 0x101121a3c 0x10112d5f0 0x1833845bc 0x1832c1d5c 0x183354e04 0x10011abc4 0x10011947c 0x100092bf0 0x10009269c 0x1000926ec 0x186a1aac0 0x186a1b258 0x186901854 0x186904a4c 0x1866d4fd8 0x1865e0014 0x1865dfb10 0x1865df998 0x183f4da20 0x101121a3c 0x1011274e4 0x181410dd8 0x18140ec40 0x181338d10 0x182c20088 0x18660df70 0x1000fcba8 0x180ed68b8) libc++abi.dylib:以 NSException 类型的未捕获异常终止

【问题讨论】:

  • 我可以理解这不是针对内存存储实现的,因为请求的全部目的是不将任何 SQLite 存储内容加载到内存中只是为了删除它......
  • @Wain:那么对于 InMemory Store,批量删除就性能而言就相当于简单地对每个对象调用 delete?苹果应该记录这一事实。

标签: ios swift core-data ios9


【解决方案1】:

根据我的经验,NSBatchDeleteRequest 不适用于 NSInMemoryStoreType。 我也在尝试同样的方法来测试我的方法,但我将不得不推迟这一点。

编辑:

添加Marcus Zarra's tweet 作为证明。

【讨论】:

  • 值得记住的是,如果您的目标是删除 all 实体的 所有 个实例,则可以通过创建一个新的 in-内存存储。没有要清理的 SQLite 文件,因此您可以丢弃对当前内存存储的任何引用。
【解决方案2】:

当您在 XCode 之外重命名某些文件时,可能会发生此错误。要解决它,您只需从项目中删除文件(右键单击 - 删除和“删除引用”)您重新导入项目中的文件,一切都会好起来的!

如果没有解决,试试这个

try persistentStoreCoordinator.executeFetchRequest(
    batchDelete, withContext:context
)

NSBatchDeleteRequest 在持久存储协调器上执行,而不是在托管对象上下文中执行。

【讨论】:

    【解决方案3】:

    我遇到了完全相同的问题。通过将内存存储更改为 NSSQLiteStoreType 来解决它。尚未研究为什么会在内存存储中发生这种情况,但我希望能解决您的问题。

    【讨论】:

      【解决方案4】:

      NSBatchDeleteRequest 应该在您的 ramStoreCoordinator 上执行,而不是 ramManagedObjectContext,因为它直接与 NSPersistenceStore 类实例一起工作:

      try persistentStoreCoordinator.executeFetchRequest(batchDelete, withContext: ramManagedObjectContext)
      

      查看此链接了解更多详情: https://developer.apple.com/videos/play/wwdc2015/220/

      希望对您有所帮助)

      【讨论】:

      • 这给了我完全相同的崩溃
      猜你喜欢
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2016-08-08
      • 2018-05-27
      • 1970-01-01
      相关资源
      最近更新 更多