在iOS中将视图控制器与视图分离有意义吗



我来自web开发背景,主要从事基于MVC的应用程序,我习惯于将代码的组件分为三组文件:控制器、模型和视图。

但在iOS应用程序中,即使也使用MVC模式,遵循同样的技术有意义吗?

UIViewController为您提供了一个默认视图,您可以在其中添加其余的子视图(UILabelUIButton…),并可以立即访问它们。语言是一样的,它不像必须处理HTML/CSS和其他东西。

但我遇到过一些iOS应用程序,其中UIView被子类化并维护在一个单独的文件中,即使它只在UIViewController中使用。因此,您必须编写自定义访问器来处理内部子视图。

我认为没有必要这样做,当然,除非您在多个地方重复使用相同的UIView或进行自定义绘图。

诚然,我们中的许多人会稍微模糊MVC行,并将少量与视图相关的代码滑入控制器中。我个人认为这很好。这并没有减少这样一个事实,即我们仍然在很大程度上遵循MVC模式(并且Cocoa类正在为视图做繁重的工作)。但是,对我来说,如果视图相关的代码扩展到琐碎之外,我会发现自己选择将视图子类化。

会有人虔诚地将UIView划分为子类,但我认为有必要采取一点实用主义。如果您添加了少量与视图相关的代码,那么通过将其抽象到一个新的UIView子类中,您的代码可读性是否得到了提高?并非总是如此。但我认为这种情况(某人在可能不需要的时候进行子类化)远不如相反的问题(某人在应该进行的时候没有进行子类)常见。

所以,你问:

我认为没有必要这样做[子类化UIView],当然,除非你在多个地方重用同一个UIView或进行自定义绘图。

我同意重用和自定义绘图(例如drawRect)是两个很好的例子。但我也要补充一个原则,如果子类化可以提高代码的可读性,因为视图足够复杂(诚然是一个主观调用),那么我将进行子类化。两个例子:

  1. 我在一个应用程序中有一个日历视图,视图控制器变得很难管理一个月中不同日子的所有单元格,等等。因此,通过子类化UIView,我能够抽象出由日历视图组成的所有子视图的丑陋细节。我不仅对主"月"视图进行了子类化,还对"月"中的"日"视图进行子类化。没有重用本身。没有自定义绘图。但这显然是正确的做法。代码更加清晰。

  2. 我越来越多地将UITableViewCell作为表视图的子类。在我的第一个项目中,我会让表视图控制器的cellForRowAtIndexPath来完成该单元格的所有复杂组成和布局。我的代码现在更容易理解了,因为在任何不使用标准细胞类型的情况下,我都会常规地对UITableViewCell进行子类化。

简言之,虽然我同意不应该强迫每个视图控制器子类化UIView,但我个人会在视图达到一定的复杂性时尝试这样做。我让代码的易读性来支配我的实践。我发现我比以前更多地对视图进行子类化,但我绝不是一直都在这样做。

最重要的是,虽然您不需要一直对视图进行子类化,但我个人认为,许多开发人员都会因为未能在应该的时候对视图(或模型)执行子类化而感到内疚。他们这样做不应该是出于某种狂热的欲望,希望符合MVC,而是应该问问自己,如果他们适当地将视图或模型子类化,他们的代码是否会更容易阅读和维护。

通常,我会有一个UIViewController<=>SingletonManager<=>实际数据源。我确实更喜欢把事情分开。如果我碰巧有一个自定义UIView,在那里我自己绘制自定义图形,我会有一个不同的文件,因为这是有意义的。即使我只在一个地方使用(你永远不知道明天你需要什么,你可能碰巧在其他地方需要它)。另外,不要忘记,你实际上已经在iOS中很好地分离了MVC:

  • NIBS/情节提要/自定义绘图
  • UIView控制器
  • 数据源

当你处理iPhone和iOS上相同应用程序之间的差异时,这可能是一个很好的模式。iPad上的DetailViewController可能是iPhone上的UINavigationController。

另一种常见的模式是,控制器与DataSource耦合,而视图与DataSource无关,并且可以在多个控制器中重用。

视图不在视图控制器中,它们要么在单独的类中,要么在视图控制器加载的nib文件中,视图控制器是为该视图编写的,因此它将所有操作和出口连接到该视图。

现在,如果您询问使用笔尖或子类,在组合和继承之间进行选择是一样的。

如果你需要一个特殊的视图,可以将UIView子类化,但如果你想拥有一个包含控件作为子视图的视图,请使用composition,使用Interface Builder来组合你的视图会更容易。

我看到只有子视图才有UIView的子类的唯一原因是为了更好的封装,但因为您的控制器是专门为视图编写的,所以没有必要进行这种封装。

最新更新