如何在 OSX 应用程序中将 CoreData 管理与 AppDelegate 分离

Posted

技术标签:

【中文标题】如何在 OSX 应用程序中将 CoreData 管理与 AppDelegate 分离【英文标题】:How to separate CoreData management from the AppDelegate in OSX applications 【发布时间】:2012-08-20 21:36:55 【问题描述】:

如果您对我的故事不感兴趣,请立即跳到底部的两个编号问题。

在this Question 中,讨论了是否将CoreData 处理与AppDelegate 分开。我决定尝试关注点分离的方式。

由于 Apple 没有为 AppKit 应用程序提供关于该主题的文档,我的问题是:

是否有说明如何将 CoreData 堆栈与 AppDelegate 分离的文档、资源甚至示例项目?

我现在的状态是这样的:

我有一个AppDelegate 和一个DataController,它是NSTreeController 的子类。 DataController 控制 NSOutlineView,它显示了我的 CoreData 模型的对象(组和叶子)。

我从 Xcode 的 CoreData(不是基于文档的)模板开始。

我将所有与 CoreData-Stack 相关的方法从 AppDelegate 移至 DataController。 我将DataController 设为单例。 我将真正的AppDelegate相关方法转发到DataController,如下:

在 AppController.m 中

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
    return [[[DataController sharedController] managedObjectContext] undoManager];

- (IBAction)saveAction:(id)sender
    [[DataController sharedController] saveAction:sender];

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
    return [[DataController sharedController] applicationShouldTerminate:sender];

所有被调用的方法当然都是在 DataController.m 中实现的

现在我可以在NSOutlineView 中添加和删除对象,撤消和重做也可以。但是,文件保存菜单项是灰色的,当我点击 cmd+s 时,我从操作系统中得到了 bing。 (当我在 AppDelegate 中有 CoreData 堆栈时,这曾经“神奇地”工作。)

当我退出应用程序时,OutlineView 中的对象通过applicationShouldTerminate 调用写入persistentStore(我看到了xml)。但是,当我重新启动应用程序时,对象并没有恢复到OutlineView。 (当我在 AppDelegate 中拥有 CoreData 堆栈时,这曾经“神奇地”工作。)

    隐藏在 CoreData 模板中的什么神奇的胶水代码使 cmd+s 工作并启用文件 - 保存菜单项? 什么隐藏代码在应用程序启动时将我的mangedObjectContext 的内容恢复到我的OutlineView

【问题讨论】:

我只为 ios 做过这个,所以它不是你想要的,但我使用的实现是基于 nachbaur.com/blog/smarter-core-data 您需要在响应者链中具有文件保存操作,因此您可以将控制器添加到响应者链或考虑在应用程序委托中实现它 - 默认情况下在响应者链中。 @Monolo 感谢您提及responder chain!我将(使用右键单击)First Responders saveAction 连接到 Save... 菜单项。由于我已经将AppDelegate 的saveAction 转发到DataController,因此启用了菜单项并且 cmd+s 也可以使用。 【参考方案1】:

我已经为 iOS 编写了一个框架来执行此操作。我的方法从 AppDelegate 中获取 Core Data 样板代码并将其移动到单例类中。这提供了与 AppDelegate 的清晰分离,消除了在视图控制器之间传递 NSManagedObjectContext 的需要,并允许您通过将框架复制到项目中来将核心数据添加到应用程序中。

您可以在http://schwiiz.org/?p=1120 阅读有关该框架的信息,或从https://github.com/chriscdn/RHManagedObject 下载。

该框架不仅仅是一个单例。它还扩展了 NSManagedObject 以简化不同线程之间的保存和获取等操作。

【讨论】:

感谢您的回答和链接。我看了你的项目,它看起来很扎实。但是,我想我遇到的问题确实与平台有关。

以上是关于如何在 OSX 应用程序中将 CoreData 管理与 AppDelegate 分离的主要内容,如果未能解决你的问题,请参考以下文章

如何在 osx 机器中将 Apple 配置文件从一个用户转移到另一个用户?

CoreData 在 OSX 框架包中找不到映射模型,但在 iOS 中可以正常工作

Swift/IOS/CoreData:如何在自动生成的 CoreData 类中将 var 定义为枚举类型?

如何在 Swift 3 中将自定义类保存为 CoreData 实体的属性?

在 OSX 中将子视图拖到超级视图之外

在使用 CoreData 的 TableView 中将行移至底部