gpt4 book ai didi

swift - 核心数据 : How to Create a Persistent Document with Singleton Entity?

转载 作者:行者123 更新时间:2023-11-28 08:40:27 24 4
gpt4 key购买 nike

我有一个使用核心数据存储文档的 swift 应用程序。每个文档包含一个实体 Settings,其中每个文档中都应存在该实体的一个实例。

该实例应该为每个新文档自动创建,并且在打开现有文档时可以访问。

我应该如何实现这样一个核心数据应用?

最佳答案

实现此类单例实体的最可靠方法是使用特殊的 getter,它会在需要时检查并创建实体。

class Document: NSPersistentDocument {
var settings: Settings {
if _settings == nil {
do {
let fetchSettings = NSFetchRequest(entityName: "Settings")
let settingsList = try self.managedObjectContext!.executeFetchRequest(fetchSettings)
precondition(settingsList.count < 2, "Too many settings object in the core data store.")
if settingsList.count == 1 {
self._settings = settingsList[0] as? Settings
precondition(self._settings != nil)
} else {
self._settings = NSEntityDescription.insertNewObjectForEntityForName("Settings", inManagedObjectContext: self.managedObjectContext!) as? Settings
precondition(self._settings != nil)
// init the settings object here
self.managedObjectContext!.processPendingChanges()
self.managedObjectContext!.undoManager!.removeAllActions()
}
} catch {
preconditionFailure("Could not retrieve/create settings object because of an unknown core data error.")
}
}
return _settings!
}
private var _settings: Settings?
// ...
}

此示例中的类 SettingsNSManagedObject 的子类,以简化对对象值的访问。您可以直接使用 NSManagedObject 而不是自己的类。

Document 类有一个私有(private)属性 _settings,它保存着 Settings 实体的当前实例。 getter settings 检查此变量,如果没有设置实例,则检查实体的托管对象上下文。

let fetchSettings = NSFetchRequest(entityName: "Settings")
let settingsList = try self.managedObjectContext!.executeFetchRequest(fetchSettings)

首先,从上下文中获取所有 Settings 实体的列表。

if settingsList.count == 1 {
self._settings = settingsList[0] as? Settings
precondition(self._settings != nil)
} else {

如果已经存在一个Settings实体,这个列表就会被检查。在这种情况下,使用现有实体。

self._settings = NSEntityDescription.insertNewObjectForEntityForName("Settings", inManagedObjectContext: self.managedObjectContext!) as? Settings
precondition(self._settings != nil)
// init the settings object here

如果不存在 Settings 实体,则会创建一个新实体并使用默认值初始化。

self.managedObjectContext!.processPendingChanges()
self.managedObjectContext!.undoManager!.removeAllActions()

这两行删除了初始化新的 Settings 实体时创建的任何撤消操作。有必要确保新文档不以“已编辑”标志开头。它还确保初始撤消不会删除创建的 Settings 对象。

在任何用户交互完成之前,尽快访问 settings 属性很重要。否则界面会出现撤消操作的问题。最好是在文档窗口的 NSWindowControllerdocument 属性中访问 settings getter:

override var document: AnyObject? {
didSet {
// access the `settings` property of the document.
}
}

为什么不将所有内容都放入 Document.init() 中?

可以在 init() 方法中为文档初始化数据,但此时托管对象上下文仍然是空的。您必须等到文档初始化完成,然后才能检查托管对象上下文中是否存在 Settings 对象。

是否可以禁用撤消而不是删除所有操作?

这实际上取决于应用程序的其余实现。但是使用这样的代码很容易实现:

self.managedObjectContext!.processPendingChanges()
self.managedObjectContext!.undoManager!.disableUndoRegistration()
self._settings = NSEntityDescription.insertNewObjectForEntityForName("Settings", inManagedObjectContext: self.managedObjectContext!) as? Settings
precondition(self._settings != nil)
// init the settings object here
self.managedObjectContext!.processPendingChanges()
self.managedObjectContext!.undoManager!.enableUndoRegistration()

关于swift - 核心数据 : How to Create a Persistent Document with Singleton Entity?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36648327/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com