Swift中的局部推理
Swift是一种令人难以置信的表达和强大的编程语言。 我们将探索Swift的一些语言功能,这些功能可使您的代码更易于阅读。
更好的按钮
让我们看一下一种常见的iOS模式,该模式在按下按钮时会打印一条消息。
如果您已完成任何iOS教程,则很有可能您之前已经看过。 选择器模式用于整个UIKit
,并不一定是不好的做法。 但是,我们可以做得更好。
当选择器声明和按钮的动作之间有很多代码时,就会出现此问题。 如果开发人员是第一次阅读本文,那么对他们而言,从根本上失去对您的功能的了解是很普遍的。
这两行代码是松散耦合的。 它们要求读者在它们之间跳转以完全理解该按钮。
让我们尝试一种新方法,使用闭包为按钮分配一个动作。
不用担心-开箱即用UIKit
是不可能的,但是让UIButton
像这样工作很容易。
除了在一个函数中包含第一个代码段之外,我们还使用了闭包来更清楚地传达单击按钮时发生的情况。 这样可以更容易理解此按钮的功能。
为您的按键操作实现闭包非常简单。 创建一个带有action
属性的自定义UIButton
子类,该属性是一个闭包。 我们在内部连接按钮的选择器,并在目标函数中执行关闭。
该解决方案可以扩展为包括UIButton
的其他动作的关闭,例如touchDown
, touchDragExit
等。
局部推理
将相关信息保持在一起可以改善本地推理。 本地推理是一种想法,使读者可以直接在代码前面理解代码,而不必去探索代码的工作原理。
在WWDC 2016上,Apple工程师作了题为“ UIKit Apps中的协议和价值导向的编程”的精彩演讲,讨论了本地推理的概念。 他们的演讲涵盖了协议以及如何利用其优势超越传统的基于继承的解决方案。
很难将代码组织策略称为无效策略,因为它们通常会根据个人喜好而有所不同。 但是,我建议,最好的代码组织形式是允许读者准确地推理代码,同时最小化遍历代码库的距离。
延迟关闭
让我们看一下另一种常见的Swift设计模式,该模式专注于改进局部推理。
一种常见的做法是在UIViewController
子类的viewDidLoad
函数中执行设置工作。
就像前面的按钮示例一样,这很好用。
注意,我们在存储的属性声明和覆盖的函数之间划分。 这是我们要重点关注的问题-查找与视图相关的所有代码通常需要搜索。
相反,我们可以使用闭包来初始化视图。
闭包被标记为lazy
因此可以在闭包内访问self
。 这允许属性引用在self
声明的任何常量,并为任何控件设置目标操作。
此策略也适用于情节提要板。 代替使用闭包,可以使用didSet
属性观察器,当故事板设置出口时会调用该属性观察器。
这对于无法在情节提要中设置的视图属性(例如拐角半径,渐变等)特别有用。它会将我们的更改本地化为视图本身。
无需将代码散布到整个文件中,我们可以将其放在一个位置。
协议一致性扩展
协议在整个Swift标准库和Cocoa Touch API中都使用。 它们提供了编译时的保证,即对象具有某些属性或功能。
这是另一个常见的模式,在视图控制器中实现集合视图的委托和数据源。
再一次,这有效。 但是,委托函数通常很长,并且往往会使实现它们的控制对象的大小膨胀。 很难说出某个属性或函数何时满足协议要求,以及它属于哪个协议。
相反,让我们在扩展中声明协议一致性,以更好地将相关代码分组在一起。
这不仅将每个协议的代码分组,而且还在实现的正上方显示协议的名称。 在类型声明时,这减少了认知负担,因为不再需要在类型名称之后编写一致性。
不需要理解对象作用的协议一致性(例如CustomStringConvertible
)可以放在类型的定义之后,其中首先需要了解有关该类型的更重要的细节。
Swift标准库的实现在扩展中大量使用协议一致性,因为更容易确定哪些功能属于哪个协议。 查看GitHub上的开放源代码仓库,亲自看看。
外卖
我们研究了Swift代码中的三种常见模式以及利用Swift功能改进局部推理的替代方法。
在编写代码时,重要的是要从阅读代码的人的角度进行思考。 这包括同事,队友,甚至您未来的自我。 良好的本地推理功能使其他人可以更轻松地理解和修改代码,从而提高其可维护性和灵活性。
尽管这些技术中的许多技术都可以视为“代码样式”,但它们可用于提高代码质量的特定目的。 用户体验设计有一些相似之处。 在这种情况下,用户界面是包含代码的文本,而用户是开发人员。 如果我们采用以用户为中心的方法来编写代码,则可以使将来的理解和修改变得更容易。
您还有其他地方可以在Swift中尝试本地推理吗? 在下面的回复中让我知道!