【发布时间】:2015-09-11 08:04:44
【问题描述】:
根据pre-release Swift 2 documentation,现在有一个#available 关键字可以与if let 或guard 语句一起用于检查API 可用性。它给出了以下示例:
let locationManager = CLLocationManager()
if #available(iOS 8.0, OSX 10.10, *) {
locationManager.requestWhenInUseAuthorization()
}
或者
let locationManager = CLLocationManager()
guard #available(iOS 8.0, OSX 10.10, *) else { return }
locationManager.requestWhenInUseAuthorization()
它(文档)声明相当于以下 Objective-C 代码:
if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {
// Method is available for use.
} else {
// Method is not available.
}
显然respondsToSelector: 仅适用于NSObject 的子类,而#available 关键字甚至适用于“纯”Swift 代码,所以我很欣赏这种优势。
然而,自从开始 iOS 开发以来,我一直被认为对于这种情况的最佳做法是检测 API 的存在,而不是依赖于引入的版本。
作为一个更具体的例子,我正在考虑 Apple 在 iOS 7 中在 NSArray 上引入 firstObject 但追溯使其可用于 iOS 4(它可用,但私有)。任何使用 respondsToSelector: 的代码都可以在 iOS
改用我错过的#available 关键字有什么好处吗?
【问题讨论】:
-
@holex 它们都是运行时解决方案。
-
我认为原因是 Swift 不允许我们创建对函数或方法的引用(文本除外),这也很危险。在 Swift 中使用任何类型的
respondsToSelector看起来很难看,因为您必须将方法的名称指定为字符串(也在 Obj-C 方法名称约定中):) 我不确定#available是一种改进,但它会帮助代码保持一致性,因为迟早会有 Swift 框架。另一方面,版本检查仅适用于系统版本,因此对于外部库,您仍然必须使用选择器检查。 -
@Sulthan External (Swift 2) 库可以使用
@availability关键字注释自己的 API。作为旁注,我不确定使用if #available...与使用NS_AVAILABLE注释的Objective-C 方法之间的兼容性。我完全同意respondsToSelector:即使在 Objective-C 中也存在问题,并且必须在 Swift 中将选择器指定为字符串真是太糟糕了。我完全赞成一种更好的方式,但#available 似乎(对我来说)是一个侧步,而不是向前迈出的一步。 -
我也有同样的感觉。
-
AFAIK
firstObject方法的情况在 Swift 中是不可能的。而且因为这是不可能的,我会假设if #available方法适用于 Swift 中的所有情况。
标签: objective-c swift swift2