北京总部

iOS开发入门——17条 Swift 最佳实践规范(下)

作者: 来源: 时间: 2016-12-30 15:51:49

承接上文:iOS开发入门——17条 Swift 最佳实践规范(上)

9.单例(Singletons)

在Swift中单例是很简单的:

class ControversyManager {    static let sharedInstance = ControversyManager()}

Swift 的 runtime 会保证单例的创建并且采用线程安全的方式访问。

      单例通常只需要访问"sharedInstance"的静态属性,除非你有不得已的原因去重命名它。注意,不要用静态函数或者全局函数去访问你的单例。

(因为在 Swift 中单例太简单了,并且持续的命名已经耗费了你太多的时间,你应该有更多的时间去抱怨为什么单例是一个反模式的设计,但是避免花费太多时间,你的同伴会感谢你的。)


10.使用扩展来组织代码

      扩展应该被用于组织代码。

      一个实例的次要方法和属性应该移动到扩展中。注意,现在并不是所有的属性类型都支持移动到扩展中,为了做到最好,你应该在这个限制中使用扩展。

      你应该使用扩展去帮助组织你的实例定义。一个比较好的例子是,一个 view controller 继承了 table view data source 和 delegate protocols 。为了使table view中的代码最小化,把 data source 和 delegate 方法整合到扩展中以适应相应的 protocol 。

      在一个单一的源文件中,在你觉得能够最好地组织代码的时候,把一些定义加入到扩展中。不要担心把 main class 的方法或者 struct 中指向方法和属性定义的方法加入扩展。只要所有文件都包涵在一个 Swift 文件中,那就是没问题的。

      反之,main 的实例定义不应该指向定义在超出 main Swift 文件范围的扩展的元素。


11.链式 Setters

       对于简单的 setters 属性,不要使用链式 setters 方法当做便利的替代方法。

正确的做法:

instance.foo = 42instance.bar = "xyzzy"

错误的做法:

instance.setFoo(42).setBar("xyzzy")

       相较于链式setters,传统的setters更为简单和不需要过多的公式化。


12.错误处理

       Swift 2.0 的 do/try/catch 机制非常棒。


13.避免使用try!

一般来说,使用如下写法:

do {    try somethingThatMightThrow()}catch {    fatalError("Something bad happened.")}

而不是:

try! somethingThatMightThrow()

       即使这种形式特别冗长,但是它提供了context让其他开发者可以检查这个代码。

       在更详尽的错误处理策略出来之前,如果把 try! 当做一个临时的错误处理是没问题的。但是建议你最好周期性地检查你代码,找出其中任何有可能逃出你代码检查的非法try!。


14.避免使用try?

       try?是用来“压制”错误,而且只有当你确信对错误的生成不关心时,try?才是有用的。一般来说,你应该捕获错误并至少打印出错误。


15.过早返回&Guards

       可能的话,使用guard声明去处理过早的返回或者其他退出的情况(例如,fatal errors 或者 thorwn errors)。

正确的写法:

guard let safeValue = criticalValue else {    fatalError("criticalValue cannot be nil here")}someNecessaryOperation(safeValue)

错误的写法:

if let safeValue = criticalValue {    someNecessaryOperation(safeValue)} else {    fatalError("criticalValue cannot be nil here")}

或者:

if criticalValue == nil {    fatalError("criticalValue cannot be nil here")}someNecessaryOperation(criticalValue!)

       这个flatten code以其他方式进入一个if let 代码块,并且在靠近相关的环境中过早地退出了,而不是进入else代码块。

       甚至当你没有捕获一个值(guard let),这个模式在编译期间也会强制过早退出。在第二个if的例子里,尽管代码flattend得像guard一样,但是一个毁灭性的错误或者其他返回一些无法退出的进程(或者基于确切实例的非法态)将会导致crash。一个过早的退出发生时,guard声明将会及时发现错误,并将其从else block中移除。


16."Early"访问控制

       即使你的代码没有分离成独立的模块,你也应该经常考虑访问控制。把一个定义标记为 private 或者 internal 对于代码来说相当于一个轻量级的文档。每一个阅读代码的人都会知道这个元素是不能“触碰”的。反之,把一个定义为 public 就相当于邀请其他代码去访问这个元素。我们最好显示地指明而不是依赖 Swift 的默认访问控制等级。( internal )

       如果你的代码库在将来不断扩张,它可能会被分解成子模块.这样做,会使一个已经装饰着访问控制信息的代码库更加方便、快捷。


17.限制性的访问控制

       一般来来说,当添加访问控制到你的代码时,最好有详尽的限制。这里,使用 private 比 internal 更有意义,而使用 internal 显然比 public 更好。(注意: internal 是默认的)。

       如有需要,把代码的访问控制变得更加开放是非常容易的(沿着这样的途径: "private" to "internal" to "public") 。过于开放的访问控制代码被其他代码使用可能不是很合适。有足够限制的代码能够发现不合适和错误的使用,并且能提供更好的接口。一个例子就是一个类型公开地暴露了一个internal cache。

       而且,代码的限制访问限制了“暴露的表面积”,并且允许代码在更小影响其他代码的情况下重构。其他的技术如:Protocol Driven Development 也能起到同样的作用。

了解更多IOS开发入门知识欢迎访问中软国际教育集团技术知识库

相关阅读

更多

中软卓越java培训地址:北京市海淀区科学院南路2号融科资讯中心C座北楼12层 联系电话:400-666-3775 邮箱账号:etc-marketing@chinasofti.com

©2008-2016 北京中软国际教育科技股份有限公司 京ICP备14058756号-2