Swift @available #available guard

Swift 2.0 中,引入了可用性的概念。对于函数,类,协议等,可以使用@available声明这些类型的生命周期依赖于特定的平台和操作系统版本。而#available用在判断语句中(if, guard, while等),在不同的平台上做不同的逻辑。

@available

用法

@available放在函数(方法),类或者协议前面。表明这些类型适用的平台和操作系统。看下面一个例子:
@available(iOS 9, *)
func myMethod() {
// do something
}
@available(iOS 9, )必须包含至少2个特性参数,其中iOS 9表示必须在 iOS 9 版本以上才可用。如果你部署的平台包括 iOS 8 , 在调用此方法后,编译器会报错。
另外一个特性参数:星号(
),表示包含了所有平台,目前有以下几个平台:

iOS
iOSApplicationExtension
OSX
OSXApplicationExtension
watchOS
watchOSApplicationExtension
tvOS
tvOSApplicationExtension
一般来讲,如果没有特殊的情况,都使用*表示全平台。

@available(iOS 9, *)是一种简写形式。全写形式是@available(iOS, introduced=9.0)。introduced=9.0参数表示指定平台(iOS)从 9.0 开始引入该声明。为什么可以采用简写形式呢?当只有introduced这样一种参数时,就可以简写成以上简写形式。同理:@available(iOS 8.0, OSX 10.10, *) 这样也是可以的。表示同时在多个平台上(iOS 8.0 及其以上;OSX 10.10及其以上)的可用性。

另外,@available还有其他一些参数可以使用,分别是:

deprecated=版本号:从指定平台某个版本开始过期该声明
obsoleted=版本号:从指定平台某个版本开始废弃(注意弃用的区别,deprecated是还可以继续使用,只不过是不推荐了,obsoleted是调用就会编译错误)该声明
message=信息内容:给出一些附加信息
unavailable:指定平台上是无效的
renamed=新名字:重命名声明
以上参数具体可以参考官方文档

#available
#available 用在条件语句代码块中,判断不同的平台下,做不同的逻辑处理,比如:

if #available(iOS 8, *) {
// iOS 8 及其以上系统运行
}

guard #available(iOS 8, *) else {
return //iOS 8 以下系统就直接返回
}
guard语句和if语句有点类似,都是根据其关键字之后的表达式的布尔值决定下一步执行什么。但与if语句不同的是,guard语句只会有一个代码块,不像if语句可以if else多个代码块。

那么guard语句的作用到底是什么呢?顾名思义,就是守护。guard语句判断其后的表达式布尔值为false时,才会执行之后代码块里的代码,如果为true,则跳过整个guard语句,我们举例来看看。

我们以今年高考为例,在进入考场时一般都会检查身份证和准考证,我们写这样一个方法:
func checkup(person: [String: String!]) {

// 检查身份证,如果身份证没带,则不能进入考场
guard let id = person["id"] else {
    print("没有身份证,不能进入考场!")
    return
}
 
// 检查准考证,如果准考证没带,则不能进入考场
guard let examNumber = person["examNumber"] else {
    print("没有准考证,不能进入考场!")
    return
}
 
// 身份证和准考证齐全,方可进入考场
print("您的身份证号为:\(id),准考证号为:\(examNumber)。请进入考场!")

}

checkup([“id”: “123456”]) // 没有准考证,不能进入考场!
checkup([“examNumber”: “654321”]) // 没有身份证,不能进入考场!
checkup([“id”: “123456”, “examNumber”: “654321”]) // 您的身份证号为:123456,准考证号为:654321。请进入考场!
上述代码中的第一个guard语句用于检查身份证,如果检查到身份证没带,也就是表达式为false时,执行大括号里的代码,并返回。第二个guard语句则检查准考证。

如果两证齐全,则执行最后一个打印语句,上面的两个guard语句大括号内的代码都不会执行,因为他们表达式的布尔值都是true。

这里值得注意的是,id和examNumber可以在guard语句之外使用,也就是说当guard对其表达式进行验证后,id和examNumber可在整个方法的作用域中使用,并且是解包后的。

我们再用if else语句写一个类似的方法:
func checkupUseIf(person: [String: String!]) {

if let id = person["id"], let examNumber = person["examNumber"] {
    print("您的身份证号为:\(id),准考证号为:\(examNumber)。请进入考场!")
} else {
    print("证件不齐全,不能进入考场!")
}
 
print("您的身份证号为:\(id),准考证号为:\(examNumber)")  // 报异常

}

checkupUseIf([“id”: “123456”]) // 证件不齐全,不能进入考场!
checkupUseIf([“examNumber”: “654321”]) // 证件不齐全,不能进入考场!
checkupUseIf([“id”: “123456”, “examNumber”: “654321”]) // 您的身份证号为:123456,准考证号为:654321。请进入考场!
我们可以看到用if else实现的方法显然不如guard实现的那么精准。而且id和examNumber的作用域只限在if的第一个大括号内,超出这个作用域编译就会报错。

猜你喜欢

转载自blog.csdn.net/u011217834/article/details/89508245