How do I do weak linking in Swift?

后端 未结 2 1512
太阳男子
太阳男子 2020-12-03 01:54

In Objective-C, if I wanted to use a specific class that\'s only present in a new version of iOS, I would do something like this:

if( [UIBlurEffect class] )          


        
相关标签:
2条回答
  • 2020-12-03 02:20

    Seems like I've figured out what you can do

    1. I used NSClassFromString() to check if class is available on device, i.e.

      if NSClassFromString("UIBlurEffect") {
          let blur = UIBlurEffect(...)
          //...
      }
      else {
          //...
      }
      
    2. It's needed to make UIKit.framework (or another corresponding framework) optional. If you create Swift-based application in XCode6-BetaX, all the frameworks wouldn't be explicitly added to the link build phase so you need to go to your target settings, add UIKit.framework as a linked framework (in 'Link Binary With Libraries' section) and to change its status to Optional. This step does the trick and I've managed to run version specific code without a problem.

    Update: You don't need to make it optional anymore, since Xcode 6 beta 6 (via @user102008)

    Update 2: You can't actually perform implicit if statement checks for nil (since Xcode 6 Beta 5). You need to assert it like that:

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

    (via @daniel-galasko)

    0 讨论(0)
  • 2020-12-03 02:20

    Just to add my two cents since I ended up using this to my immediate dismay upon distributing the app to our testers. There is a bug in the Swift compiler (Xcode <= 6.1.1) whereby when building in Release mode the compiler actually doesn't return nil when calling NSClassFromString.

    To check me simply change your configuration to Release and see how she crashes.

    I ended up having to explicitly check for iOS versions or a simple respondsToSelector call in other place.

    So where my code looked like this:

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

    I ended up having to use this instead

    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!
            }
    

    This question dealt with the same issue - UIAlertView is crashing app on iOS 7

    0 讨论(0)
提交回复
热议问题