我如何在Swift中做弱链接?

在Objective-C中,如果我想要使用一个只存在于新版iOS中的特定类,我会这样做:

if( [UIBlurEffect class] ) { // do something with UIBlurEffect } else { // gracefully fallback to old behavior } 

不过,相当于Swift:

 if UIBlurEffect.self != nil { let blur: UIBlurEffect = UIBlurEffect(...) // ... else { // ... } // also occurs with NSClassFromString("UIBlurEffect") 

不具有相同的function。

如果在NSNewFeature可用的环境中运行,一切都很好。 但是如果这个类没有被定义,那么在启动应用程序时就会出现链接错误:

 dyld: Symbol not found: _OBJC_CLASS_$_UIBlurEffect 

那么如何在Swift中做弱链接呢?

编辑添加UIBlurEffect作为具体的例子。

好像我已经知道你能做什么了

  1. 我使用NSClassFromString()来检查类是否在设备上可用,即

     if NSClassFromString("UIBlurEffect") { let blur = UIBlurEffect(...) //... } else { //... } 
  2. 需要使UIKit.framework (或其他相应的框架)可选。 如果你在XCode6-BetaX中创build了基于Swift的应用程序,那么所有的框架都不会被明确地添加到链接构build阶段,所以你需要去你的目标设置,添加UIKit.framework作为链接框架(在“链接二进制库“部分)并将其状态更改为” Optional这一步做的伎俩,我已经设法运行版本特定的代码没有问题。

更新 :由于Xcode 6 beta 6(通过@ user102008),您不必再使其成为可选项,

更新2 :你实际上不能执行隐含的if语句检查为零(自Xcode 6 Beta 5以来)。 你需要像这样断言:

  if NSClassFromString("UIBlurEffect") != nil { let blur = UIBlurEffect(...) //... } else { //... } 

(通过@ daniel-galasko)

自从我把这个应用程序分发给我们的testing人员之后,我立即加了两分钱。 在Swift编译器(Xcode <= 6.1.1)中存在一个错误,在Release模式下编译时,编译器实际上在调用NSClassFromString时不返回nil。

要检查我只是将您的configuration更改为释放,看看她是如何崩溃。

我结束了不得不显式检查在其他地方的iOS版本或简单的respondsToSelector调用。

所以,我的代码看起来像这样:

  if NSClassFromString("UIVisualEffectView") != nil { //use the blur safely } else { //abandon blur! try something safer } 

我最终不得不用这个来代替

 switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) { case .OrderedSame, .OrderedDescending: //go wild with blur case .OrderedAscending: //blur shall not pass here! } 

这个问题处理了同样的问题 – UIAlertView崩溃iOS 7上的应用程序