5

我想创建一个使用

  • 迅速
  • 核心数据
  • 以标准 macOS 方式工作的“文档”[自定义扩展,包含与该文档相关的所有数据的单个“文件”/文件包装器]

这似乎是不可能的。该文件非常清楚地指出

NSPersistentDocument 不支持某些文档行为:文件包装器。[..]

这让我认为在 CoreData 中处理图像的常用方法 -带有“允许外部存储”的二进制数据并将它们保存到不同的位置,将 URL 存储在数据库中 - 不能与 NSPersistentDocument 一起使用。我希望我的用户能够对我的“文件”执行通常的 Finder 操作(复制、移动到外部存储、从外部备份恢复),并且需要将我的所有数据放在一个包中。

文件存储的 SQL 版本在保存时会产生通常的三重堆栈 - .sqlite、.sqlite-shm、.sqlite-wal - 作为“文档”是无用的。

有没有我忽略的解决方案?(示例非常少;Big Nerd Ranch 示例也没有解决这个问题;Marcus Zarra 和 Objc.io 都没有涉及 NSPersistentDocument)。

4

2 回答 2

4

唯一可以NSPersistentDocument按照您希望的方式工作的选项是将图像直接存储在数据库中。您需要实体上的二进制数据属性,但不能打开该Allows External Storage选项。

如果您打开此选项,Core Data 将根据大小决定是将图像直接存储在数据库中还是存储在文档所在文件夹内的隐藏文件夹中:

隐藏文件夹

(我使文件夹cmd-shift-.在Finder中可见)。示例文档被命名Test 1.doof,它包含三个图像:

文档窗口

您可以看到隐藏文件夹.Test 1_SUPPORT/EXTERNAL DATA包含两个文件,它们是两个较大的图像(1.3 MB 和 494 KB)。第三个只有 50 KB 存储在里面Test 1.doof。如果您移动Test 1.doof到另一个文件夹,隐藏的文件夹将被留下。在该其他文件夹中打开文件会导致两个图像丢失。

如果将二进制数据放入与其余数据一对一关系的单独实体中,则将图像存储在数据库中并不是那么糟糕,如下所示:

数据模型

这样图像就不会干扰任何搜索或排序操作。NSPersistentDocument免费为您提供许多很酷的功能,因此您应该尽可能使用它。

两个补充说明:

  • 如果您打开Allows External Storage一个属性,您不必关心 URL 或存储图像的位置,Core Data 会为您做到这一点(但对于基于文档的应用程序来说不是一种有用的方式)。
  • 这些shmwal文件是“有时”出现的临时文件,对于没有外部存储的数据库也是如此。如果它们粘在一起,您可以在应用关闭时安全地移除它们。
于 2017-09-09T12:24:16.197 回答
1

如果您想在文档中放置更多内容,而不仅仅是一个数据库,那么您应该实现NSDocument而不是NSPersistentDocument. 在这种情况下,您不会获得对 CoreData 的内置支持,但您可以将文档用作多种文件类型的容器。

另请参阅NSDocument 和 CoreData 是一种可能的组合,还是 NSPersistentDocument 是唯一的方法?

于 2017-08-11T17:50:10.577 回答