Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bridgeToObjectiveC and makeObjectsPerformSelector in Swift beta 5

I had this code with a completion handler working in Xcode 6 beta 4 that no longer works in Xcode 6 beta 5.

dropsToRemove.bridgeToObjectiveC().makeObjectsPerformSelector("removeFromSuperview")

Full method...

func animateRemovingDrops(dropsToRemove: [UIView]) {
    println(__FUNCTION__)
    UIView.animateWithDuration(1.0,
        animations: {
            for dropView in dropsToRemove {
                let x = CGFloat(UInt(arc4random_uniform(UInt32(UInt(self.gameView.bounds.size.width) * 5)))) - self.gameView.bounds.size.width * 2
                let y = self.gameView.bounds.size.height
                dropView.center = CGPointMake(x, -y)
        }}, completion: { finished in
                dropsToRemove.bridgeToObjectiveC().makeObjectsPerformSelector("removeFromSuperview")
        })
}

The error is '[UIView]' does not have a member named 'bridgeToObjectiveC'

Note that the CGFloat and Uint casting in the method is for a beta 4 workaround, I just haven't updated that part yet. That issue is covered at: ‘CGFloat’ is not convertible to ‘UInt8' and other CGFloat issues with Swift and Xcode 6 beta 4

I thought the solution for dealing with the completion handler might be to treat the array as an NSArray as detailed in: What is the swift equivalent of makeObjectsPerformSelector?

(dropsToRemove as NSArray).makeObjectsPerformSelector("removeFromSuperview")

However, assuming I got the syntax right, simply results in another error 'makeObjectsPerformSelector' is unavailable: 'performSelector' methods are unavailable

Is this a new Swift bug, or something I'm missing in the release notes?

like image 469
kasplat Avatar asked Jan 11 '23 02:01

kasplat


1 Answers

The bridgeToObjectiveC and bridgeFromObjectiveC functions are not available in Xcode 6.0 beta 5. Instead, cast to/from the appropriate Foundation type when you need to use that type's API on a Swift object. For example:

var arr = ["One", "Two"]
(arr as NSArray).indexOfObject("One")

Apple has warned against (or explicitly made unavailable) using performSelector and related methods since the first Swift beta. Presumably any such API that were still available before beta 5 were unintentionally so.

As the question you cited notes, you can use map to call a function/method on every element of an array. You can also use filter, find or a for-in loop, or after casting to NSArray, one of the enumerateObjects methods. Note that many consider it bad style to use the functional-programming constructs (map, filter, reduce, find) for tasks that aren't "functional" -- that is, to run code that has side effects. So a for-in loop might be the cleanest way to do what you're after.

like image 87
rickster Avatar answered Jan 16 '23 20:01

rickster