不管是swift语言还是其他什么编程语言,如果我们在使用中,能掌握一部分小技巧的话,往往都能达到事半功倍的效果,今天和大家分享的就是swift开发中的一些小技巧,一起来看看吧。
通过Guard来验证方法
Swift的guard语句让代码更简洁、更安全。guard语句会检查一到多个情况,找出不符合else部分的调用。而else部分需要return,break,continue或throw语句来终止方法的执行,也就是说终止程序控制的执行。
我们使用guard语句来减少代码混乱,并避免在if/else语句中的嵌入。由于在guard语句的else部分中,代码必须转移程序控制的范围,如果出现无效的情况,简单地采用if语句来调用return语句更为安全。在编译时这些bug仍有可能出现。如果guard语句的情况通过的话,在我们的范围中,解包后的可选值仍旧可用。
class ProjectManager {
func increaseProductivityOfDeveloper(developer: Developer) {
guard let developerName = developer.name else {
print("Papers, please!")
return
}
let slackMessage = SlackMessage(message: "\(developerName) is a great iOS Developer!")
slackMessage.send()
}
}
用Defer管理程序控制流
defer语句会推迟包含这个命令的代码执行,直到当前范围终止。也就是说,在defer语句中清理逻辑是可以替换的,而且只要离开相应的调用范围,这段命令就肯定就会被调用。这样可以减少冗余步骤,更重要的是增加安全性。
func deferExample() {
defer {
print("Leaving scope, time to cleanup!")
}
print("Performing some operation...")
}
// Prints:
// Performing some operation...
// Leaving scope, time to cleanup!
简化单例模式(Singleton)
在任何语言中对单例模式的使用都属于热议话题,不过它仍是大多数开发人员非常熟悉的模式。在Objective-C中,实现单例模式包括多个步骤,以便确保不会多次创建单例模式类。在Swift中这种使用有了大幅简化。下面我们会看到在Objective-C中实现单例模式的代码行数,是在Swift中实现单例模式代码的两倍。除此之外,由于使用了dispatch token,不仅可读性较差,也很难记住。
Objective-C:
@implementation MySingletonClass
+(id)sharedInstance {
static MySingletonClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
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"]
对数组中的每个值执行函数筛选(filter),返回Bool值。在结果数组中,只会返回true值,而不会返回false值。下面我们从ints数组中筛选奇数:
let evenInts = ints.filter { return ($0 % 2 == 0) }
print("evenInts: \(evenInts)") // prints: evenInts: [0, 2, 4, 6, 8]
reduce比map和filter更复杂,不过因为非常有用,花时间学习也是有价值的。第一个参数就是第一个reduce值(在下面的案例中为0)。第二个参数是访问之前reduce值和数组现值的函数。在本例中,我们的函数是将之前的函数值简单加到数组的现值中。
let reducedInts = ints.reduce(0, combine: +)
print("reducedInts: \(reducedInts)") // prints: reducedInts: 45
// defined another way:
let reducedIntsAlt = ints.reduce(0) { (previousValue: Int, currentValue: Int) -> Int in
return previousValue + currentValue
}
print("reducedIntsAlt: \(reducedIntsAlt)") // prints: reducedIntsAlt: 45
通过map,filter,reduce方面的技巧,就能减少筛选时和处理集合时的工作量,并增加可读性,方便以后的人维护。
文章来源:极客头条
推荐学习:http://www.maiziedu.com/course/772/
有疑问加站长微信联系(非本文作者)