转眼间,Swift已经一岁半多了,这门新的编程语言确实是值得称赞的。
guard语句
guard语句,顾名思义,就是守护。guard语句判断其后的表达式布尔值为false时,才会执行之后代码块里的代码,如果为true,则跳过整个guard语句,我们举例来看看。
我们在这举个考研进入考场时检查身份证和准考证的栗子:
func checkup(person: [String: String!]) {
// 检查身份证,如果身份证没带,则不能进入考场
guard let cardId = person["cardId"] else {
print("没有身份证,不能进入考场!")
return
}
// 检查准考证,如果准考证没带,则不能进入考场
guard let examNumber = person["examNumber"] else {
print("没有准考证,不能进入考场!")
return
}
// 身份证和准考证齐全,方可进入考场
print("您的身份证号为:\(cardId),准考证号为:\(examNumber)。请进入考场!")
}
checkup(["cardId": "123456"]) // 没有准考证,不能进入考场!
checkup(["examNumber": "654321"]) // 没有身份证,不能进入考场!
checkup(["cardId": "123456", "examNumber": "654321"]) // 您的身份证号为:123456,准考证号为:654321。请进入考场!
异常处理
说到异常处理,OC中的异常处理真的不好很好的,它没有Java那么好用,也没有C++中的异常处理那样处理的那么完善,所以swift下的异常处理,给了iOS开发中的异常处理带来了很大的提升。
在swift1.0如果要处理异常,要么使用if else语句或switch语句判断处理,要么使用闭包形式的回调函数处理,再要么就使用NSError处理。以上这些方法都不能像Java中的try catch异常控制语句那样行如流水、从容不迫的处理异常,而且也会降低代码的可读性。
在Swift 2.0中Apple提供了使用throws、throw、try、do、catch这五个关键字组成的异常控制处理机制。下面我们来举例看看如何使用,我用使用手机刷朋友圈为例。
首先我们需要定义异常枚举,在Swift 2.0中Apple提供了ErrorType协议需要我们自定义的异常枚举遵循:
enum WechatErro: ErrorType {
case NoBattery // 手机没电了
case NoNetwork // 手机没网络了
case NoDataStream // 手机没数据流量了
}
我们定义了导致不能刷微信的错误枚举’wechatError。然后定义一个检查是否可以刷微信的方法checkIsWechatOK():
func checkIsWechatOK(isPhoneHasBattery: Bool, isPhoneHasNewwork: Bool, dataStream: Int) throws {
guard isPhoneHasBattery else {
throw WechatErro.NoBattery
}
guard isPhoneHasNewwork else {
throw WechatErro.NoNetwork
}
guard dataStream > 10 else {
throw WechatErro.NoDataStream
}
}
这里需要注意,在方法名后有throws关键字,意思为该方法产生的异常向上层抛出。在方法体内使用guard语句对各种状态进行判断,然后使用throw关键字抛出对应的异常。然后我们定义刷微信的方法:
func playWechat(isPhonehasBattery: Bool, isPhoneHasNetwork: Bool, dataStream: Int) {
do {
try checkIsWechatOK(isPhonehasBattery, isPhoneHasNewwork: isPhoneHasNetwork, dataStream: dataStream)
print("放心刷,一切都好着呢")
} catch WechatErro.NoBattery {
print("手机都没电,刷个毛啊")
} catch WechatErro.NoNetwork {
print("没有网络了,洗洗睡吧")
} catch WechatErro.NoDataStream {
print("又没流量了,去蹭wifi")
} catch {
print("见鬼了")
}
}
上述的代码示例中,首先检查是否可以刷微信的方法前使用try关键字,表示允许该方法抛出异常,然后使用了do catch控制语句捕获抛出的异常,进而做相关的逻辑处理。
playWechat(true, isPhoneHasNetwork: true, dataStream: 60) // 放心刷,一切都好着呢
playWechat(false, isPhoneHasNetwork: true, dataStream: 60) // 手机都没电,刷个毛啊
playWechat(true, isPhoneHasNetwork: false, dataStream: 60) // 没有网络了,洗洗睡吧
playWechat(true, isPhoneHasNetwork: true, dataStream: 5) // 又没流量了,去蹭wifi
这套异常处理机制使Swift更加的全面和安全,并且提高了代码的可读性,非常棒。
available检查
作为iOS开发者,我们经常需要适配老版本的iOS,这就会面临一个问题,一些新特性或一些类无法在老版本的iOS中使用,所以在编码过程中经常会对iOS的版本做以判断,就像这样:
if NSClassFromString("NSURLQueryItem") != nil {
// iOS 8或更高版本
} else {
// iOS8之前的版本
}
以上这只是一种方式,在Swift 2.0之前也没有一个标准的模式或机制帮助开发者判断iOS版本,而且容易出现疏漏。在Swift 2.0到来后,我们有了标准的方式来做这个工作:
if #available(iOS 8, *) {
// iOS 8或更高版本
let queryItem = NSURLQueryItem()
} else {
// iOS8之前的版本
}
defer关键字
在Java语言中,有try/finally这样的控制语句。这种语句可以让我们在finally代码块中执行必须要执行的代码。在Swift 2.0中,Apple提供了defer关键字实现同样的效果。
func checkSomething() {
print("CheckPoint 1")
doSomething()
print("CheckPoint 4")
}
func doSomething() {
print("CheckPoint 2")
defer {
print("Clean up here")
}
print("CheckPoint 3")
}
在打印出“CheckPoint 2”之后并没有打印出“Clean up here”,而是“CheckPoint 3”,这就是defer的作用,它对进行了print("Clean up here")延迟。