如何在Xib文件中实例化视图控制器导致难以理解和调试的代码?

在iOS编程简介:Big Nerd Ranch Guide中 ,作者说他们总是以编程方式创建视图控制器 ,并且在Xib文件中实例化视图控制器会导致难以理解和调试的项目。

具体来说,这有什么问题呢? 你会遇到哪些困难?

是否有任何具体的例子,如何在代码中创建视图控制器来避免这些问题?

报价在简介>风格:

我们将始终以编程方式创建视图控制器。 一些程序员将在XIB文件中实例化视图控制器。 我们发现这种做法导致难以理解和调试的项目。

他们谈论实例化。 如果你有两个视图控制器A,B,你可以在A的实现中分配/ init B,或者你可以在A的XIB中删除对B的引用。 在这两种情况下,B都可以在XIB中定义(Big Ranch书建议将复用视图控制器使用XIB)。


无论如何,这是区别:

CitySelectionVC *citySel = [[[CitySelectionVC alloc] initWithCities:self.cities] autorelease]; [self.navigationController pushViewController:citySel animated:TRUE]; 

VS

 citySel.cities = self.cities; [self.navigationController pushViewController:citySel animated:TRUE]; 

第一种情况是代码中的显式实例化。 它告诉我:

  • VC现在已创建。
  • 它需要城市工作。

第二个块中的代码引用在XIB中实例化的sockets。 它告诉我:

  • VC在未知时间实例化,具有未知要求。
  • 我正在经过城市。

我喜欢第一种风格,因为它更明确,并让我控制对象的寿命。

在iOS 5中,您可以使用Storyboard创建转换并在控制器之间传递信息。 参见WWDC2011的会话309。

为了完整起见,以下是我在Big Nerd Ranch论坛上收到Joe Conway (本书作者之一) 的答案 :

“当发生低内存警告时,视图控制器的视图被删除以释放内存。当该视图控制器的视图需要返回到屏幕上时,它会重新加载其XIB文件。

如果XIB文件中存在控制器对象(或实际上是任何非视图对象),则还会重新创建这些对象。 不知道这可能会使您的应用程序处于不一致状态,因为可能已经保持状态的控制器(或对持有状态的模型对象的持有引用)将被销毁。

可以说每个人都应该知道这一点并采取适当的行动来解决这个问题。 然而,这个论点存在一些问题:不是每个人都知道这一点,即使他们知道这一点,他们也被迫打开XIB文件来查看控制器层次结构并通读代码。 这使事情难以维持。“

在我看来,这不是一个黑白,正确或错误的情况,更多的是个人偏好的情况。 这也是一个古老的争论 – “真正的程序员在代码中做到这一点”的论点自大型机时代以来一直存在。

在代码中构建视图控制器的可能优点:

  • 界面的所有方面都在一个地方,因此您可以通过阅读一个文件来确切了解发生了什么。
  • 如果您认为UI构建器中的拖放操作很复杂,那么创建视图可能会更简单。
  • 在界面生成器中获得细粒度的像素完美控制可能会很痛苦,特别是如果你已经习惯了像Photoshop这样的工具进行图层和布局控制。

柜台观点:

  • 除非你有经验或者只是那种倾向,否则从代码中了解视觉界面的外观和感觉是非常困难的。
  • 与最终用户和设计人员一起使用代码构建的接口几乎是不可能的。
  • 有时它只是更快地拖动和拍打控制并轻推它们直到它是正确的。

最终,这是一个适合你的案例。 我倾向于两种方式,取决于界面的复杂程度,它需要多快的速度,以及(坦率地说)我当时的情绪……

这是一个哲学问题。 如果它全部是代码,那么我很难想象外观和布局是否正确。 另一方面,使用.xib文件意味着您没有任何一个地方可以确保所有sockets实际连接起来。

本地化对于.xib文件来说IMO也会变得更容易 – 你当然可以用代码来做这件事,但是当按钮改变大小时,它可能会很棘手。

这是非常正确的:“真正的程序员在代码中执行它”但我在调试时没有看到问题,除非你在调试时没有关注UI问题。 它意味着修复您必须通过IB修复它的UI问题以及调试时不应该查看的问题。

开发人员在通过XIB进行UI时遇到的最大问题是在团队中开发它并将其放入SVN。 如果您遇到任何冲突,并且您需要合并这两个代码,则必须使用XML。 有时,手动解决XIB中的冲突变得非常困难。 如果你通过编码来完成它,你就可以很容易地完成它(因为你知道哪条线导致了什么问题,要保留什么以及要删除什么)。

我希望这可以帮助您决定您应该在XIB中保留什么以及您需要通过编码做什么。

除了(正如其他人已经指出的那样)是一种错误的二分法,我发现这个论点具有误导性:

虽然你现在有两个地方可以找到可能来自的地方,但是当你在XIB中实例化视图控制器时,只要你需要同一个视图控制器的两个配置,你就会在你向前走时失去“仅代码”路线。

根据我的个人经验,我看到或工作的项目中的大部分代码膨胀来自于不愿意将配置与function分离,即强行“在代码中执行”而不是“使用配置加载XIB”。

在最糟糕的项目中,通过简单地将配置视为数据,可以轻松避免数十个类 – 并且可以更好,更强大的代码,因为它可以更彻底地运用。

所以在我看来,使用XIB 甚至实例化其他视图控制器不仅不会降低代码库的可维护性,而且可以帮助实际改进它

使用XIB有一个警告:
你必须互相交谈 – 你必须在你的团队中建立一些约定,你必须谈论放置(或计划放置)究竟在哪为什么

然而,建立惯例和讨论架构是你不管项目甚至编程语言应该做的事情,如果你不想最终导致巨大的维护噩梦……


使用XIB的一些技巧:

  • 在编写视图控制器时,对断言要宽容 – 如果你有一些先决条件,那么在你的viewDidLoad中放一个NS(Parameter)Assert并确保exception断点处于活动状态,这样你就可以轻松找到丢失的连接(包括那些来自代码!)。
  • 为对象提供有意义的标签,因为自动生成的名称很快就会变得无用 – 当您的视图层次结构变得复杂时,如果在“视图”中有“视图”,则在大纲中看不到多少 – 兄弟姐妹 – 三层深入另一个视图或有十个UILabel将动态填充数据。
  • 设置编辑器以在大多数时间执行实时自动调整“编辑器>canvas>实时自动调整”。 只有在您没有明确需要时才禁用它。