Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
741 views
in Technique[技术] by (71.8m points)

objective c - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...