Swift:约定好,字符串坏

我真的很喜欢Apple API。 我认为它们是合乎逻辑的且经过精心设计。 但是他们的某些选择只会使我瘫痪。 一种选择是使用字符串作为键路径或标识符。 在编译期间不检查字符串,您可以很容易地错误键入它们。 否则名称可能会更改。 哦,我还记得那些漫长的夜晚,当我尝试在UITableView中查找内存泄漏时,发生了这种情况,因为我忘记在Interface Builder中为我的单元格设置了reuseIdentifier 。 那些痛苦和遗憾的时刻。

另一个问题是,我的代码很容易出错,因为我在整个项目中都重复使用了单元格,这导致我创建带有标识符的常量头,这很麻烦,因为我必须不断将其与笔尖名称和标识符同步。 总体而言,我喜欢的字符串太多了。 其他开发人员的代码看起来和使用起来更加痛苦,因为它看起来像是直接从Apple教程中复制粘贴的代码,这些代码在各处都具有Massive View Controllers,并且具有零可重用性和可扩展性。 可悲的是,这样的代码甚至在今天都可以看到,并且在过去,平均而言,也没有比这更好的了:

因此,大约7年前的一天,我开始反思自己的事迹和周围人的事迹。 我觉得我是一个罪人,那不是永远的。 我脑子里有一个特别的问题:“我们为什么要使用Apple约定,却害怕创建自己的约定?”然后,我环顾四周,发现基于CoreData的ActiveRecords确实有自己的约定,我的团队也有。 它们只是没有形式化,没有得到很好的利用。 我很开悟。

我决定,我想创建约定以简化从辉煌的一天到永恒的代码。 但是我感到,公约同时是危险的,因为每个人都必须遵守它们。 因此,我记录了他们的心声,并在团队中谨慎而勤奋地向整个团队宣传。

我在那个时候恢复了我的行动和想法,但是我用Swift重写了它们,向您展示了如何自己分析和创建约定。

形式分析使我发现了一个发现。 所有单元格都有标识符,这是其类名的直接派生词。 而且,所有视图的所有笔尖都具有与该特定视图的类相同的名称。

首先,我摆脱了细胞问题。 我创建了一个约定,那就是我们所有的单元类名称和重用标识符应相等:

注意,我立即创建了一个负责类型字符串化的函数。 在那个时候我们不需要它,但这是常见的切入点,可以在以后需要时允许扩展。

在ObjC时代,我们可以重载扩展中的任何属性,但是我没有这样做,而是创建了IDPTableViewCell子类。 为什么? 很简单,我们与其他开发团队的代码具有互操作性。 而且,如果我超载了UITableViewCell redirectIdentifier ,我会弄乱其他人的代码,他们可能会使用不同的甚至根本不使用任何约定。

然后,我想,我想摆脱表视图中的字符串,这意味着我需要从UINib中删除字符串(那时没有UINib ,只有旧的NSBundle.loadNibNamed ,但是正如我之前提到的,我希望了解我的故事):

我创建了许多其他方法,从用于表视图的API中完全删除了字符串(我保证很快就会开源)。 我的生产代码开始看起来像这样:

虽然这不是LOC部门的重大改进,但此代码还是有一个巨大的胜利:我不必再费神笔尖中的字符串和标识符了。

我想提及的另一种情况是完全不同的,但也与约定有关。 经过分析,我发现项目中的所有视图控制器笔尖都具有与视图控制器类相同的名称。 这与苹果公司本身所强加的惯例是一致的。 但是真正的问题是,我的产品负责人(希望您在读这篇文章时能在地狱中度过一个愉快的假期)想要不同的笔尖,这些笔尖的布局完全不同,适用于不同的设备,那时没有尺寸级别。 那就是我发现的时候,如果需要的话,这些约定应该可以扩展。 因此,我有了解决方案—重载了抽象视图控制器类的nibName属性。 我真的很高兴拥有该类,因为否则我将不得不创建它并相应地重构所有代码。

因此,我想到的另一个约定是:“为您计划从中继承的所有基础组件创建子类”。 在我的情况下,它们是UIViewUIViewController抽象子类和模型抽象类。 我所有与项目相关的实体都从它们子类化。 起初它们是空的,但是当产品负责人开始执行一些任务时,我真的很高兴他们能够影响整个项目。

就是这样,伙计们。 祝您有美好的一天,无论您身在何处,都要保持干燥。

PS这行仅是一个占位符,提醒我自己要使用反字符串约定将链接链接到回购协议。 如果我要到2017年2月才这样做, 向阅读以下内容的任何人致意: 请提醒我一下