问题标签 [nspersistentcontainer]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
736 浏览

swift - Core Data iOS10 + 中的 NSPersistentContainer 轻量级迁移

我添加了一个新的数据模型。为实体添加了一些新属性。告诉 xCode 使用新版本。我是否认为如果使用NSPersistentContainer,这就是我所要做的,xCode 会自动为我执行轻量级迁移?

我很困惑,因为许多关于轻量级迁移的帖子说我现在必须创建一个NSPersistentStoreDescription将一些属性设置为 True 并将其传递给NSPersistentContainer

但是我认为这现在是多余的。我知道 .shouldMigrateStoreAutomatically.shouldInferMappingModelAutomatically默认都是True,所以我知道我不再需要将它们设置为 true,但是自 iOS 10 以来是否需要任何代码?

0 投票
1 回答
173 浏览

core-data - NSPersistentContainer, performBackgroundTask, calling perform does nothing

I'm just started working on a new project and thought I'd try out Core Data's NSPersistentContainer instead of writing my own stack.

I just stumbled upon this issue where calling the perform method of the managedObjectContext actually does nothing if the task was started as part of NSPersistentContainer's performBackgroundTask.

Here's a snippet of what I'm currently doing to demonstrate the issue. Note that I have a DispatchGroup to ensure that the tasks are performed in sequence.

0 投票
1 回答
104 浏览

objective-c - 将 Objective-C 核心数据迁移到 Swift 持久化容器

当 Apple 添加新的 PersistentContainer 类时,他们更改了数据存储的位置。这意味着如果您添加一个新的 PersistentContainer,它不会选择当前数据库,而是创建一个。根本问题是新商店位于另一个文件夹中。如何为 PersistentContainer 指定文件夹以便它获取旧存储?

0 投票
0 回答
304 浏览

ios - 具有大型数据集的 NSPersistentContainer 和 NSFetchedResultsController

我们最近将我们的应用程序切换到使用NSPersistentContainer来设置我们的核心数据堆栈。删除样板文件(例如自动使用保存通知和合并处理)对我们很有吸引力,而且它应该设置得非常高效。

但是,我们在导入大型数据集时遇到了问题。首先让我告诉你,我们的数据模型相当复杂——很多一对多的关系和实体。

Core Data 堆栈过去被设置为使用NSManagedObjectContext附加到的私有队列NSPersistentStoreCoordinator来执行后台队列的持久性。主队列上下文将是该上下文的子上下文;作为主队列上下文的子级创建的私有队列上下文以处理保存。在发明之前建立的相当标准NSPersistentContainer

然而,当我们开始注意到随着我们的数据集变得越来越大时,分析应用程序会告诉我们 Core Data 在主线程上占用了大量的 CPU 时间。切换到NSPersistentContainer似乎可以解决这个问题。主线程上的活动少了很多。我们推测这是因为通过主队列的流量较少(因为NSPersistentContainers 提供的后台队列newBackgroundQueue()被设置为直接保存到存储协调器;它们不是主队列上下文的子队列)。

在数据集增长之前,这似乎一切都很好。我们注意到,当处理大约 15,000 条记录(有时多达 10-15,000 个与这些记录相关的对象)时,如果NSFetchedResultsController设置为观察这些对象,则在保存背景上下文时,UI 会挂起。很糟糕。长达 1 分钟。显然这是不可取的。

以下是我们的持久化容器的设置方式:

我们通过 获取私有队列上下文newPrivateQueueContext(),执行我们的工作,然后保存。大数据集导致NSFetchedResultsController挂起。

Apple 建议设置viewContext.automaticallyMergesChangesFromParent = true并且还建议直接保存到持久存储比保存到父子配置中的中间人(视图上下文)更有效:

两个上下文都连接到相同的 persistentStoreCoordinator,后者作为它们的父级用于数据合并。这比在父上下文和子上下文之间合并更有效。

我们实际上已经设法解决了这个问题,方法是删除automaticallyMergesChangesFromParent = true并更改我们的私有队列上下文的配置方式:

实际上,这在父子配置中配置了我们的主上下文和子上下文 - 根据 Apple 的说法,这应该是效率较低的。

这行得通!数据正确保存到磁盘(已验证),数据有效(已验证),不再NSFetchedResultsController挂起!

然而,这提出了几个问题:

  • 为什么NSPersistentContainer在处理大型数据集时,Apple 推荐的设置结果的方法是锁定主队列?不是应该更有效率吗?我们缺少什么吗?
  • 有没有人遇到过这样的问题,也许以不同的方式解决了它?我们找不到太多关于设置NSPersistentContainer在线处理大型数据集的信息。
  • 你能看出我们设置堆栈的方式有什么问题吗,或者建议对配置进行改进?
  • 看起来好像直接保存到持久化存储,然后viewContext合并更改效率低于父子配置?有人可能对此有所了解吗?

我应该补充一点,我们试图NSFetchedResultsController通过设置和改进谓词来提高效率fetchBatchSize,但无济于事。

0 投票
2 回答
1283 浏览

ios - ViewContext 未从 newBackgroundContext() 接收更新

堆栈溢出中已经有一个类似的问题,但它对我不起作用。

在我的应用程序中有一个用例,我必须观察数据库更改才能执行某些操作。为了接收更新,我订阅了 NSManagedObjectContextObjectsDidChange通知(针对 ViewContext)并且我打开了automaticallyMergesChangesFromParent.

但是,如果我updatedelete其他上下文中的对象(使用newBackgroundContext()),我不会收到对象确实更改通知,但它对inserting新对象非常有效。

有人可以指导我为什么它仅适用于插入,即使在启用后也不适用于更新和删除automaticallyMergesChangesFromParent?如果这是实际行为,还有其他方法可以解决我的用例吗?

文档(in NSManagedObjectContext.h.automaticallyMergesChangesFromParent说:

上下文是否自动合并保存到其协调器或父上下文的更改。当上下文固定到非当前查询生成时,不支持将此属性设置为 YES。

我试过的

  • 我通过测试是否已在视图上下文中注册更新/删除的对象来进行调试。是的,那些已经注册了。
  • 我用NSFetchResultController它测试了同样的东西,但不幸的是,我不能使用NSFetchResultController,因为我使用自定义视图来表示数据
  • 另外,我尝试创建一个新的privateQueueConcurrencyType上下文并设置viewContext为父级,它出人意料地开始工作,所以问题只是在使用时,newBackgroundContext()但根据文档,它应该可以正常工作,因为两者都使用相同NSPersistentStoreCoordinator

提前致谢!

0 投票
0 回答
192 浏览

core-data - Core Data 使用 AppGroups 加载持久存储

我需要访问我的主要目标中的持久容器以及应用程序扩展。所以我创建了一个框架来共享代码,并创建了一个 NSPersistentContainer 子类,如下所示:

在 AppDelegate 中,我这样做是为了加载持久存储:

当我尝试加载 NSManagedObjectModel 时它崩溃了。我不明白我在这里做错了什么?

0 投票
1 回答
237 浏览

swift - 如何为 NSPersistentContainer 和 NSPersistentCloudKitContainer 创建同名但根据版本设置的变量?

我无法将令人兴奋的核心数据堆栈更改为 NSPersistentCloudKitContainer,因为这只是 iOS 13 及更高版本的支持功能,但我希望为 iOS 13 及更高版本设置该功能,同时为早期版本设置 NSPersistentContainer。

我在使用 swift 和 iOS 方面有相当多的经验,但从来没有为版本控制和某些 var 做这样的事情。

这是我在使用 iOS 13 之前的正常操作:

这是我想在 iOS 13 或更高版本的任何设备上使用的,但仍将第一部分代码用于 iOS 12 及更早版本。

如果可能的话,我希望两个版本具有相同的变量,而不会重新声明错误,如果这甚至可能的话,如果那不可能,我想要一个不需要完全重写我的所有存储和检索的解决方案核心数据,数据。

0 投票
0 回答
59 浏览

swift - 更改容器目标时删除了核心数据

我已经在我的应用程序中使用标准设置的核心数据很长时间了,但是当我更改 NSPersistentContainer 时,所有内容都被删除了。我预计新的 NSPersistentContainer 会是空的,但是当我回到原来的 NSPersistentContainer 时,现在那里也没有任何东西(之前有超过 10,000 个对象)

原始标准设置

但是,当我使用以下代码更改 Persistent 容器以与扩展程序共享应用程序数据时,应用程序数据似乎全部消失了。

当我回到使用以前的设置时 - 即

代替

没有从数据库返回数据。是否有可能改变持久化容器的位置真的可以删除原始容器中的所有数据。我以为它会创建两个单独的容器,所以我可以切换回原来的容器,一切都会在那里。

0 投票
1 回答
626 浏览

ios - 使用 NSPersistentContainer 在后台保存托管对象更改

我在一些地方(比如这里的高分答案)读到,将主托管上下文作为后台托管上下文的子级以节省 save() 时间并提高 UI 响应能力是一种很好的做法。

但问题是,由 iOS 模板代码创建的主要托管上下文与 Persistent Store Coordinator 相关联,并且似乎没有支持的方式来改变它。我尝试了以下代码:

但得到了一个 NSException:

我的问题是:

1)这是否意味着,要实现上述架构,我不能使用 NSPersistentContainer 并且必须使用我自己的代码设置核心数据堆栈?

2)鉴于 NSPersistentContainer 是新的 API,我认为它必须有一些方法来达到相同的效果(在后台线程中保存托管对象的更改)。我想知道它是什么?我正在考虑以下方法,其中 save() 仅在保存上下文中调用,而不是在主上下文中调用。但它更复杂,不像上面的那样自然。有没有更简单的方法?

更新:再想一想,这种方法不起作用,因为合并是基于通知的。如果在主上下文中未调用 save(),则不会触发任何通知。

嗯,我想知道是否可以创建另一个 mainQueueConcurrencyType 的 NSManagedObjectContext,按照我最初的意愿进行设置,然后用它替换 NSPersistentContainer 创建的那个?

感谢您的任何建议。

0 投票
0 回答
38 浏览

swift - 使用 2 个 NSPersistentContainer

是否可以将多个 NSPersistentContainer 连接到项目中的同一个商店。我正在更改使用 2 NSPersistentStoreCoordinator 的现有实现以使用 NSPersistentContainer。