我如何在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
作为具体的例子。
好像我已经知道你能做什么了
-
我使用
NSClassFromString()
来检查类是否在设备上可用,即if NSClassFromString("UIBlurEffect") { let blur = UIBlurEffect(...) //... } else { //... }
-
需要使
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上的应用程序