Ios 为什么苹果的文档显示从UIApplicationLegate获取ManagedObjectContext是不好的?

Ios 为什么苹果的文档显示从UIApplicationLegate获取ManagedObjectContext是不好的?,ios,core-data,nsmanagedobjectcontext,Ios,Core Data,Nsmanagedobjectcontext,只是好奇为什么ManagedObjectContext在创建时应该传递给UIViewController,而不是从UIApplicationLegate获取它们 文档说这会使你的应用程序更加死板,但我没有看到何时使用哪种模式的细微差别 谢谢 这主要是因为您希望在UIViewController中使用依赖项注入,而不仅仅是从UIApplication中获取所有信息,这样可以保持代理干净,而不是充满引用攻击 这也是为了与MVC模式保持一致: 模型 视图控制器(仅用于视图逻辑) 控制器(用于协调视图和

只是好奇为什么ManagedObjectContext在创建时应该传递给UIViewController,而不是从UIApplicationLegate获取它们

文档说这会使你的应用程序更加死板,但我没有看到何时使用哪种模式的细微差别


谢谢

这主要是因为您希望在UIViewController中使用
依赖项注入
,而不仅仅是从UIApplication中获取所有信息,这样可以保持代理干净,而不是充满引用攻击

这也是为了与MVC模式保持一致:

  • 模型

  • 视图控制器(仅用于视图逻辑)

  • 控制器(用于协调视图和模型)


  • 我倾向于不同意这种模式

    首先,我试图将核心数据视为一个实现细节,而作为任何实现细节,它都应该隐藏在一个好的外观后面。facade是我为模型对象公开的接口。例如,如果我有两个模型对象
    Cource
    Student
    ,任何Cource都可以有多个学生。我不想让控制器承担起设置谓词和排序描述符的责任,并跳过所有核心数据环,只是为了获得特定类的学生列表。有一种非常有效的方法可以在模型中公开此信息:

    @interface Cource (StudentAccess)
    -(NSArray*)studentsStortedByName;
    @end
    
    然后在模型类中一次性地实现丑陋的东西。隐藏核心数据的所有复杂细节,无需传递托管对象上下文。但我如何才能找到来源,它必须从某个地方开始,对吗?是的,但您不需要将其暴露给控制器。添加这样的方法也是完全合理的:

    @interface Cource (CourceAccess)
    +(Cource*)caurceByID:(NSString*)courceID;
    +(NSArray*)allCources;
    +(NSArray*)courcesHeldByTeacher:(Teacher*)teacher;
    @end
    
    这也有助于最小化控制器之间的依赖关系。减少模型和控制器之间的依赖性。假设我有一个
    CourceViewController
    和一个
    StudeEnviewController
    是,我没有将核心数据细节隐藏在门面后面,也希望传递托管对象上下文,那么我最终会得到一个指定的初始值设定项,如下所示:

     -(id)initWithManagedObjectContext:(NSManagedObjectContext*)moc
                               student:(Student*)student;
    
    然而,有了一个好的外观,我最终得到了以下结论:

     -(id)initWithStudent:(Student*)student;
    

    尽量减少外观后面的依赖项,支持依赖项注入,这也使得更改内部实现更加容易。传递托管对象上下文鼓励每个控制器为基本内容实现自己的逻辑。以
    studentsSortedByName
    方法为例。起初可能是按姓/名排序,如果以后改为姓/名排序,你必须找到每个对学生进行排序的控制员并进行更改。一个好的facade方法需要您在一个方法中进行更改,并且所有控制器自动获得免费更新。

    想象一下,我让您做一些任务,比如粉刷房间。如果我只是告诉你“去粉刷房间”,你需要问我很多问题,比如:

    • 哪个房间
    • 油漆在哪里
    • 刷子在哪里
    • 我应该用垂布吗
    简言之,没有我的帮助,你将无法完成任务。如果你每次都要依赖我,你就不会是一个很灵活的画家。解决这个问题的一个办法是,我从一开始就给你所有你需要的东西。我会说:“请用这桶油漆和这把刷子来粉刷348号房间,不要用抹布。”而不是“去粉刷一个房间。”现在,你已经得到了你所需要的一切,不用我再帮你了,你就可以开始工作了。你是一个灵活得多的工人,因为你不再依赖我了


    同样的情况也适用于视图控制器(通常是对象);与其让他们依赖于某个特定的对象(如应用程序委托),不如给他们所需的一切。这不仅适用于托管对象上下文,也适用于他们工作所需的任何信息。

    苹果文档试图培育最广泛适用和可持续的设计模式。 依赖注入是首选,因为它允许最灵活、可扩展、可重用和可维护的设计

    随着应用程序变得越来越复杂,使用类似于将上下文停在应用程序委托中的准单例将出现故障。在更复杂的应用程序中,您可能会将多个上下文绑定到多个商店。您可能希望同一视图控制器/视图对在不同的时间显示来自不同上下文的数据,或者可能最终在不同的线程/操作上显示多个上下文。你不能在应用程序委托中堆积所有这些上下文

    如果您有一个具有单个上下文的简单应用程序,那么将准单例与应用程序委托一起使用可以很好地工作。过去,我在几个较小的应用程序上使用过它,但没有立即出现问题,但当应用程序超时增长时,我确实在几个应用程序上遇到了可伸缩性问题


    使用哪种模式取决于您的发货限制以及您对evolution应用程序在整个生命周期中的性能的最佳猜测。如果它是一个小的一次性应用程序,那么应用程序代理准单例将正常工作。如果应用程序更复杂,可能会变得更复杂,或者可能会产生其他相关的应用程序,这些应用程序将重用现有组件,那么依赖项注入就是一种方法

    我看不出你在哪里不同意苹果——你只是更进一步,隐藏了背景。你不会主张让你的视图控制器从app delegate或其他单身人士那里获取学生或课程列表,是吗?@Caleb-不是从app delegate那里获取的,但我不会羞于从
    课程
    类的类方法中获取课程列表。我不同意排序和谓词属于模型层。排序和谓词仅是接口所必需的,因此它们属于控制器。放