Swift编程的15个技巧(4)

Swift:

class MySingletonClass { static let sharedInstance = MySingletonClass() private init() { } } 通过协议扩展减少重复的代码

在Objective-C中,我们通过分类来扩展已有的类型,不过这种做法对协议无效。Swift允许向协议中添加功能,使用Swift可以扩展单协议(甚至在标准数据库中的那些!),并将其应用在实现协议的类中。协议扩展足够将我们的整个编程范式从面向对象式改为面向协议式。这个概念的关键在于,我们默认通过协议来添加功能,而不是通过类,以便增加代码的可复用性。想要了解更多面向协议编程的知识,请查看这个 视频 ,摘自WWDC 2015。

创建全局Helper函数

全局变量和函数经常被合称为“坏东西”,不过事实是两者都能让代码更干净,真正的坏东西是全局状态。全局函数经常需要 全局状态 来完成相关工作,因此很容易理解它们为什么会有这样的坏名声。下面是一些 Grand Central Dispatch 的helper函数样例,不是建立在全局状态之上,而且多少有些语法糖(指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用)的性质。下面我们会采用dispatch_after函数,用Swift的方式来解包:

import Foundation /** Executes the closure on the main queue after a set amount of seconds. - parameter delay: Delay in seconds - parameter closure: Code to execute after delay */ func delayOnMainQueue(delay: Double, closure: ()->()) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), closure) } /** Executes the closure on a background queue after a set amount of seconds. - parameter delay: Delay in seconds - parameter closure: Code to execute after delay */ func delayOnBackgroundQueue(delay: Double, closure: ()->()) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), closure) }

下面是新解包的函数样例:

delayOnBackgroundQueue(5) { showView() }

下面是未解包的函数样例:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) { showView() }

用Swift语法来解包C函数,让我们的代码更易于一眼理解。找到你最喜欢的函数,试一下吧!只要在正确方法命名上尽责,将来程序的维护者肯定感激我们。如果我们将上面的方法签名修改为delay(delay: Double, closure: ()->()),这就成了不负责任的方法命名反例,因为dispatch_after需要 GCD 队列,而从名称中看不出来使用的哪个队列。然而,如果我们使用的代码库在主线程所有方法的执行上有既定规范,除非在名称或评论上另有指示,delay(delay: Double, closure: ()->())就可以是一个正确的方法名称。无论我们如何命名helper函数,它们都是为了通过包装样本代码节省时间,让代码更易读。

扩展集合性能

Swift增加了一些方法,帮助我们对集合进行简洁的查询和修改。这些集合方法受到了函数式语言的启发。我们使用集合将多个值保存到一个单独的数据结构中,通常我们也会查询和修改集合。这些函数是基于Swift的标准数据库构建,协助简化常见的任务。为了协助诠释下面这些函数,我们使用了这些样例:let ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。

对集合中的每个值执行闭包映射(map),之后返回填充有映射值的映射结果类型数组。下面我们将Int数组转化为字符串数据:

let strings = ints.map { return String($0) } print("strings: \(strings)") // prints: strings: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/cd439da48ebc0babfdbad55c4cef0bf6.html