【问题标题】:CoreData - Use AppDelegate, singleton or property on viewcontroller for managedObjectContext?CoreData - 在视图控制器上为 managedObjectContext 使用 AppDelegate、单例或属性?
【发布时间】:2014-03-03 11:58:04
【问题描述】:

首选哪种方式来处理CoreDatamanagedObjectContexts?为什么?

我经常看到三种不同的方式,还有一种奖励方式:

  • AppDelegate中声明,让视图控制器依赖于AppDelegate
  • 一个sharedManager singleton class
  • Property on each view controller 并让父视图控制器设置它

  • 用于 UIViewController 的 category 公开 shared manageObjectContext

在您看来,每种方法的优缺点是什么?

【问题讨论】:

    标签: ios objective-c design-patterns core-data uiviewcontroller


    【解决方案1】:

    AppDelegate中声明,让视图控制器依赖AppDelegate

    恶心。不应涉及应用程序委托,因为数据模型不是应用程序级委托活动。所有其他类都依赖于应用程序委托也是不合适的。

    Apple 在示例代码中采用此选项,因为它很简单,但这并不正确。

    一个 sharedManager 单例类

    提供良好的知识管理、放置迁移逻辑的良好位置(如果需要在映射模型之外),并且可以将整个应用程序从应用程序中的任何远程同步方面抽象出来。

    很多人不喜欢单例(全局状态),但它们确实有其用途。

    每个视图控制器上的属性并让父视图控制器设置它

    相当不错 - 但取决于(根)父级首先从哪里获取 MOC。

    UIViewController 的类别,公开共享的 manageObjectContext

    同样,取决于 MOC 的来源。这比整个代码中的显式引用更好地隐藏了知识,但是交叉耦合到错误的类仍然很糟糕。

    【讨论】:

    • 我建议改为共享 PersistentStoreCoordinator。
    • 有人可以解释为什么Apple会这样做:当我们开始一个新项目并勾选Core Data选项时在AppDelegate中声明核心数据?既然你说在 AppDelegate 中声明 Core Data 是个大忌?
    【解决方案2】:

    这些我都不做。

    无论如何,建立整个堆栈可能需要相当长的时间,尤其是在涉及迁移的情况下。因此,我总是异步构建堆栈,并在堆栈已完全建立时触发通知。

    有兴趣的人可以收听通知,并在那个时间点开始使用堆栈。

    大多数应用只有一个堆栈,可以在应用委托中启动。您可以在主视图控制器的 viewDidLoad 方法中收听通知(该方法已经触发,但时间 application:didFinishLaunchingWithOptions: 运行)。

    在创建堆栈时,您可以获得响应式 UI 的额外好处。您唯一需要做的就是确保 UI 在没有数据的情况下是合理的(这比在堆栈加载时让它无响应更好)。

    【讨论】:

    • 就我个人而言,我认为你已经把这个复杂化了。在应用程序加载时通过显示启动屏幕稍等片刻是可以接受的。如果你想处理这个异步,如果用户必须等待堆栈加载到主视图中,你可能必须显示一个活动指示器,这是一个糟糕的权衡。无论如何,我不认为你在这里回答了这个问题。 OP 要求与上下文进行通信的最佳实践。如果您回电 AppDelegate,传递参考信息等。您的答案是解决不同的问题。
    【解决方案3】:

    我的观点是,您应该将堆栈移出 AppDelegate,并创建一个可以从 AppDelegate 启动的单独类。如果您愿意,可以将对该数据类的引用传递到 viewController 层次结构中。这样,您的 AppDelegate 不负责堆栈,您可以通过传入模拟数据对象来测试您的类。我认为您希望避免在视图控制器和 AppDelegate 之间创建依赖关系。您的 ViewController 不需要了解您的 AppDelegate。这是完全不必要的依赖。将依赖项放在一个类别中也不能解决问题。通过将堆栈移到 AppDelegate 之外,如果您不想依赖 AppDelegate 来启动它,您可以选择使堆栈类成为单例。这是对单例模式 IMO 的一个很好的使用。

    这里有 2 个要点,第一个在 Objc 中,第二个在 Swift 中,应该可以帮助您入门。在 Swift 中,我直接将其设为单例。

    https://gist.github.com/philosopherdog/4219a1b8f446acf8c8dc

    https://gist.github.com/philosopherdog/cab11bb626f3bbe776a22ea408c900e1

    【讨论】:

      猜你喜欢
      • 2015-10-20
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      相关资源
      最近更新 更多