【问题标题】:Need help to understand MVC better in Objective C需要帮助以更好地理解 Objective C 中的 MVC
【发布时间】:2015-03-27 02:37:36
【问题描述】:

我实际上是 Objective C 的新手。我在 Objective C 中做一些项目只有 4 个月。而且我已经尽我所能在我的项目中实现 MVC,尽管它可能很简陋。

所以到目前为止我所学到的基本上是(简单地说):模型:数据和逻辑。查看:图形输出。控制器:输入和更新模型/视图。 CMIIW。所以基本上控制器是中间人,它只是为模型内部的逻辑提供输入,然后接收模型的输出以在视图中转换为图形表示,对吗?并且这些信息将通过委托相互传递,对吗?

如果有这个案例研究:

我有一个控制器,它有一个视图(将从情节提要中自动创建)和许多子视图。我们将这些子视图(及其模型)称为 A、B 和 C。

所以我会有这些课程:

A_ModelB_ModelA_ViewB_ViewViewController

还有这些代表:

A_ModelDelegatesB_ModelDelegatesA_ViewDelegatesB_ViewDelegates,都应该放到ViewController类中。

比如说,如果A_View 中有UITextViewUIButtonB_View 中有UITableViewUIImageView

应用程序的流程是这样的: A_View 对象中的 textView 将获取输入,并且其中有一个 IBAction 方法用于调用 A_ModelDelegates 中的一个委托将输入数据发送回 ViewController 对象。这反过来会将数据发送到A_Model 对象并进行处理。然后模型会将其发送回控制器以更新A_View对象,并将B_Model对象作为B_View中tableView和imageView参数的输入。现在 tableView 使用 AFNetworking 库从网络序列化。所以B_Model 将获取数据作为NSDictionary 对象并通过其委托将其发送回控制器。并且控制器将使用它来填充和更新B_View 对象中的tableView。

现在我的问题是:

  1. 这样的MVC思路正确吗?

  2. 控制器的主要工作只是作为模型、视图及其各自代表(可能非常大的集合)实例的容器。而且它只会在它们之间传递数据?

  3. 如果我们使用AFNetworking从B_Model对象中的网络获取数据,应该有成功和失败 块在里面,对吧?在故障块中,如果我们想发出警告对话框,AFAIK 我们有两种不同的方法来做到这一点,在 iOS 7 中使用 UIAlertView 在 iOS 8 中使用 UIAlertController。我们应该把它放在哪里?该模型?控制器?还是风景?
  4. 我的印象是它应该放在控制器内部,因为UIAlertControllerthere's this line: [self presentViewController:alert animated:YES completion:nil]; 这是正确的吗?那么我是否还必须将UIAlertViewDelegate 放入容器中,并在需要时通过模型的委托从模型内部执行它们(例如,在模型无法从网络获取数据时在失败框中)?如果有很多警报视图怎么办?
  5. 而对于tableView的序列化,我应该把数据源和委托放在哪里呢?控制器还是视图?模型不应该知道视图,所以数据源和委托不应该放在那里,对吗?如果我们想把它放在控制器中,如果有很多表视图会被放入不同的子视图中怎么办?如果有很多表视图,数据源和委托方法会非常大,因为每个表视图的所有输入/输出都必须放在那里。
  6. 还是按照上面的问题。我的序列化方式正确吗?模型从网络获取数据并将它们制成字典,该字典将通过其委托传递给控制器​​。然后字典将用于填充表格视图。

提前致谢。

【问题讨论】:

    标签: ios objective-c iphone uitableview model-view-controller


    【解决方案1】:

    我不确定,如果我在所有方面都理解你的 Q 是正确的。也许在cmets之后A会改变。

    这样的MVC思路对吗?

    基本上,但请查看其余答案。

    控制器的主要工作只是作为模型、视图和它们各自代表的(可能非常大的集合)实例的容器。而且它只会在它们之间传递数据?

    不,它不仅仅是数据流的粘合剂。它也是控制流的粘合剂。我认为你有一个误解:

    即使模型内部有逻辑很性感,也是一种危险的想法。这样做可以使您的模型更具体地应用于应用程序。仅将模型视为数据集合,仅具有“代码”以保持其自身的一致性。即使是 MVC 也是一种常见的模式,这并不意味着你必须一直适应它。

    如果我们在 B_Model 对象中使用 AFNetworking 从网络中获取数据,其中应该有一个成功和失败的块,对吧?在故障块中,如果我们想发出警告对话框,AFAIK 我们有两种不同的方法来做到这一点,在 iOS 7 中使用 UIAlertView 和在 iOS 8 中使用 UIAlertController。我们应该把它放在哪里?该模型?控制器?还是风景?

    我的印象是它应该放在控制器中,因为 UIAlertController 有这样一行:[self presentViewController:alert animated:YES completion:nil];它是否正确?那么我是否还必须将 UIAlertViewDelegate 放入容器中,并在需要时通过模型的委托从模型内部执行它们(例如,在模型无法从网络获取数据时在失败框中)?如果有很多警报视图怎么办?

    您应该将获取数据的代码放入控制器层,而不是模型层。这不仅仅是收集数据,因为可能存在改变控制流的错误。

    而对于tableView的序列化,我应该把数据源和委托放在哪里呢? 您不序列化视图。您序列化使用表格视图显示的模型(或另一个视图,如果您选择了一个项目,或者......您通常有一个模型和多个视图来显示它的一部分。)

    序列化从控制器层开始。它处理提取数据、错误……

    控制器还是视图?模型不应该知道视图,所以数据源和委托不应该放在那里,对吗?如果我们想把它放在控制器中,如果有很多表视图会被放入不同的子视图中怎么办?如果有很多表视图,数据源和委托方法会非常大,因为每个表视图的所有输入/输出都必须放在那里。

    您可以有一个额外的控制器来进行序列化。控制器可以是委托或动作目标,但不必是其中之一。控制器是控制控制流的(可能是自定义的)类的简单实例。

    由于模型是序列化的,而不是视图,所以没有任何相关性,哪个视图显示哪些信息。

    还是按照上面的问题。我的序列化方式正确吗?模型从网络获取数据并将它们制成字典,该字典将通过其委托传递给控制器​​。然后字典将用于填充表格视图。

    控制器从网络获取数据,将其存储在模型中并更新视图(如果它们不能自动执行此操作)。

    【讨论】:

    • 我明白你的意思。但这不会打破本应成为 MVC 第一规则的“智能模型、瘦控制器、哑视图”行话吗?
    • 这个“#1 规则”来自什么编程语言使用的什么框架?为什么可以概括?在 Cocoa 中,模型通常使用 Core Data 建模。除了简单的存储之外,Core Data 还有一个逻辑:保持数据一致。您可以添加与数据本身密切相关的逻辑。但是,与数据之外的地方相连的逻辑与所有可能发生的事情联网,使简单的事情变得复杂。您不觉得胖模型方法会导致问题吗?在 Cocoa 中,M 和 V 之间几乎没有联系,就像在其他一些框架中一样。
    • 嗯,我总是在关于 MVC 的文章中读到这个行话/规则说了很多遍。所以我认为这是任何 MVC 实现中的规范。这不是常态吗?
    • 他们说:胖模型比胖控制器好。这从一开始就令人怀疑。他们为什么这么说?当模型依赖于网络通信(包括使用的框架、格式……)时,它如何可重用?您应该以不同的方式阅读它:永远不要参加肥胖课程。在 Cocoa 中,这不依赖于 MVC 层。
    • IC。但如果是这样的话,控制器就会被一堆委托和逻辑臃肿。 AFAIK,一个场景中只能有一个视图控制器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2013-04-18
    • 2014-11-25
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多