首页 > 代码库 > iOS开发入门——17条 Swift 最佳实践规范(下)

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

  文章来源:http://www.zretc.com/technologyDetail/433.html

  承接上文: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 = http://www.mamicode.com/criticalValue else { fatalError("criticalValue cannot be nil here")}someNecessaryOperation(safeValue)

  错误的写法:

  if let safeValue = http://www.mamicode.com/criticalValue { someNecessaryOperation(safeValue)} else { fatalError("criticalValue cannot be nil here")}

  或者:

  if criticalValue =http://www.mamicode.com/= 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开发入门知识欢迎访问中软国际教育集团技术知识库

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