这里每天分享一个 iOS 的新知识,快来关注我吧
前言
你可能会在代码中看到 #available 和 @available 两个关键字,它们都用作 API 可用性相关的功能,但是它们之间有什么区别呢?今天就来讲讲这两个关键字。
#available 和 #unavailable
#available 关键字主要是用作 if、 while 和 guard 这几个条件语句的,可以在运行时来查询某个 API 的可用性。
先看下定义:
#available(platform version , platform version ..., *)
platform 参数支持使用 iOS 、 macOS 、 watchOS 和 tvOS 作为平台名称,然后一个空格带上相应的版本号,然后最后有个 *,代表在其他任何平台上。
比如某个 API 在 iOS 15 及以上才能使用,我们的 App 最低兼容 iOS 12 以上,那么在用到这个 API 的时候就需要用这个关键字来做分别的实现:
if #available(iOS 15, *) {
// 使用 iOS 15 可用的 API
} else {
// 使用 iOS 15 以下的 API 实现
}
或者用 guard 实现:
guard #available(iOS 15, *) else {
// 使用 iOS 15 以下的 API 实现
return
}
// 使用 iOS 15 可用的 API
需要注意的是当有多个 #available 条件时,不能使用 && 和 || 等逻辑运算符,但是可以用逗号,比如判断在 iOS 15 或 macOS 13 以上可用:
if #available(iOS 15.0, *) || #available(macOS 13.0, *) {
// 在 iOS 15 和 macOS 13 以上可用
}
在 swift 5.6 中,还引入了取反的操作,即:#unavailable,代表 #available 否定条件的语法糖。但是 * 参数是隐式的,不需要写:
if #unavailable(iOS 15) {
// 使用 iOS 15 以下的 API 实现
}
@available
@available 是一个声明属性,可以将其应用在类或方法声明上,还可以指定这些类或方法支持的平台。
看下声明:
@available(platform version , platform version ..., *)
platform 是平台,支持 iOS、 macCatalyst、 macOS / OSX、 tvOS 或 watchOS,或任何附加 ApplicationExtension 的平台(例如 macOSApplicationExtension)。然后一个空格后面加上版本,最后的星号 * 代表其他平台都可用:
比如 MyClass 在 iOS 15 以上可用:
@available(iOS 15, *)
class MyClass {
}
多个平台限制可以用逗号分隔:
@available(macOS 10.15, iOS 15, watchOS 6, tvOS 13, *)
class MyClass {
}
在 MyClass 这个类的声明上面加了 @available 意味着这个类只能在 macOS 10.15, iOS 15, watchOS 6, tvOS 13 以上使用。
当 @available 作用在方法上时,还可以标记这个方法的引入版本、过期版本、废弃版本和代替方法等信息:
@available(iOS 15, *)
class Person {
@available(iOS,
introduced: 15,
deprecated: 16,
obsoleted: 17,
renamed: "newRun",
message: "这个方法在 iOS 15 引入,在 iOS 16 过期,在 iOS 17 废弃,请尽快替换新方法 newRun")
func run() { }
}
举个例子
假如我们有个类叫 Person,Person 中有个方法 run,可以这样声明:
class Person {
func run() { }
}
在 iOS 17 发布之后,苹果给了 run 方法实现的新 API,这时候为了使用新的 API 实现 run 方法,我可能会起一个新的方法 newRun,但是这个方法只能在 iOS 17 以上使用,所以就必须标记 @available(iOS 17, *)
class Person {
@available(iOS 17, *)
func newRun() { }
func run() { }
}
那么当使用 Person 的人用到 newRun 方法的时候,如果是在 iOS 17 以下,就会报错:'newRun()' is only available in iOS 17 or newer,这这时候就需要用 @available 先做版本判断:
let person = Person()
if #available(iOS 17, *) {
person.newRun()
} else {
person.run()
}
点击下方公众号卡片,关注我,每天分享一个关于 iOS 的新知识
本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!