Swift核心数据结构

Swift Core Data structure

我在 Swift 中开始使用 Core Data,正如我在许多教程中看到的那样,每个人都只在 AppDelegate.swift 中使用 ManagedObjectContext

在我的应用程序中,我想在多个视图中使用 ManagedObjectContext,因此我需要一些共享该对象的机制。

我认为创建一个 class 可以在任何地方管理 ManagedObjectContext 是一个很好的方法。

我不确定 ManagedObjectContext 和其他与核心数据相关的对象是否有可能用单例初始化,这是否是一个好方法?或者我最好在每个视图之间转移ManagedObjectContext(我不明白为什么会更好)。

您对核心数据的使用有什么意见/建议或好的演示吗?

基本上有三种选择:

  1. 将上下文从应用程序委托对象传递到初始视图控制器,然后分别从源视图控制器传递到目标视图控制器。

  2. 由于可以从任何地方访问应用程序委托对象,因此请将核心数据堆栈(如模板所建议的那样)留在AppDelegate中并简单地编写

    let appDelegate = NSApplication.sharedApplication().delegate as! AppDelegate
    let managedObjectContext = appDelegate.managedObjectContext
    
  3. 将整个 Core Data 堆栈移动到一个单独的 class 并将其用作单例

    class CoreDataManager: NSObject {
    
      class var sharedManager : CoreDataManager {
        struct Singleton {
          static let instance = CoreDataManager()
        }
        return Singleton.instance
      }
    
      // MARK: - Core Data stack
    
      lazy var managedObjectModel: NSManagedObjectModel = {
        // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
        let modelURL = NSBundle.mainBundle().URLForResource("MyModel", withExtension: "momd")!
        return NSManagedObjectModel(contentsOfURL: modelURL)!
      }()
    
    ...
    
      lazy var managedObjectContext: NSManagedObjectContext = {
    
    ...
    

    并用

    调用它
    let managedObjectContext = CoreDataManager.sharedManager.managedObjectContext
    

本题has been asked many times on Whosebug. You ask if you should pass the ManagedObjectContext from view to view. The official answer from Apple is yes

When you create a view controller, you pass it the context it should use. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It’s typically the responsibility of the application delegate to create a context to pass to the first view controller that’s displayed.

A view controller typically shouldn’t retrieve the context from a global object such as the application delegate—this makes the application architecture rigid. Neither should a view controller create a context for its own use (unless it’s a nested context). This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.

这叫做dependency injection。您是否选择使用它取决于您。依赖 AppDelegate 或创建单独的单例来访问 managedObjectContext 会使您的代码更“僵化”,正如他们所说,并且在未来可能会导致问题。

话虽这么说,很多人都使用单例来做这种事情。这很容易,而且成本不会立即显现出来。除了我在上面发布的 SO link 之外,Google 搜索“依赖注入”将比我在这里用几句话更好地解释优势。