【问题标题】:bridgeToObjectiveC and makeObjectsPerformSelector in Swift beta 5Swift beta 5 中的 bridgeToObjectiveC 和 makeObjectsPerformSelector
【发布时间】:2014-08-04 19:33:27
【问题描述】:

我的这段代码带有一个在 Xcode 6 beta 4 中工作的完成处理程序,而在 Xcode 6 beta 5 中不再工作。

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

完整方法...

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")
        })
}

错误是“[UIView]”没有名为“bridgeToObjectiveC”的成员

请注意,该方法中的 CGFloat 和 Uint 转换是针对 beta 4 的解决方法,我只是尚未更新该部分。该问题涵盖在: ‘CGFloat’ is not convertible to ‘UInt8' and other CGFloat issues with Swift and Xcode 6 beta 4

我认为处理完成处理程序的解决方案可能是将数组视为 NSArray,详见: What is the swift equivalent of makeObjectsPerformSelector?

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

但是,假设我的语法正确,只会导致另一个错误“makeObjectsPerformSelector”不可用:“performSelector”方法不可用

这是一个新的 Swift 错误,还是我在发行说明中遗漏的东西?

【问题讨论】:

  • 他们可能只是将其添加到禁止列表中。 dropsToRemove.map { $0.removeFromSuperview() } 很短。
  • @BrianNickel,使用 map 产生副作用是一个危险的优先级。这不是地图的目的。
  • @drewag 很公平:for drop in dropsToRemove { drop.removeFromSuperview() } 仍然比桥接代码短得多。
  • @BrianNickel,而且这是类型安全的 :)
  • 谢谢@BrianNickel。应该将其发布为答案吗?我总是很高兴看到使用桥接和选择器的更好方法...

标签: objective-c swift


【解决方案1】:

bridgeToObjectiveCbridgeFromObjectiveC 函数在 Xcode 6.0 beta 5 中不可用。相反,当您需要在 Swift 对象上使用该类型的 API 时,可以转换为/从相应的 Foundation 类型转换。例如:

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

自第一个 Swift 测试版以来,Apple 已警告(或明确禁止)使用 performSelector 和相关方法。大概在 beta 5 之前仍然可用的任何此类 API 都是无意的。

正如the question you cited 所说,您可以使用map 对数组的每个元素调用函数/方法。您还可以使用filterfindfor-in 循环,或者在转换为NSArray 之后使用enumerateObjects 方法之一。请注意,许多人认为将functional-programming 构造(mapfilterreducefind)用于非“功能性”的任务是不好的风格——也就是说,运行具有side effects。因此,for-in 循环可能是完成您所追求的最干净的方式。

【讨论】:

  • 谢谢@rickster。我还必须将let chosenViewIndex = cardButtons.bridgeToObjectiveC().indexOfObject(sender.view as PlayingCardView) 之类的代码替换为let chosenViewIndex = find(cardButtons, sender.view as PlayingCardView)!,这样更清晰,但由于 find() 的可选结果存在问题,我之前没有使用过
  • @rickster 很好的答案!to run code that has side effects你能解释一下副作用或提供一些相关的链接
  • 添加了一些维基百科链接来解释这些术语。
【解决方案2】:

Apple 的某个人表示,这些 bridgeToObjectiveCbridgeFromObjectiveC 函数是私有函数,即仅供 Apple 内部使用,它们会消失。

如果您恰好在开发者计划中,我会尝试在开发者论坛中找到该声明的链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-08
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    相关资源
    最近更新 更多