1

我将 XCode 升级到 6.3 / Swift 1.2,我看到扩展错误。下面是我对 UINavigationItem 的扩展,用于隐藏 backButton 文本。

extension UINavigationItem {
    func backBarButtonItem() -> UIBarButtonItem {
        return UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
    }
}

编译时,我收到以下错误

带有 Objective-C 选择器“backBarButtonItem”的方法“backBarButtonItem()”与“backBarButtonItem”的 getter 冲突

不再可以使用扩展来覆盖方法吗?

4

2 回答 2

2

问题是您没有覆盖属性,而是试图提供在同一类中定义的属性(的获取器)的不同实现

首先要说的是 6.3 中发生了一些变化(参见发行说明 (18391046, 18383574)

Swift 现在可以检测 Swift 类型系统中的重载和覆盖与通过 Objective-C 运行时看到的有效行为之间的差异。

也就是说,您正在backBarButtonItem扩展中创建一个新方法。但是UINavigationItem已经有一个backBarButtonItem属性,并且分别自动为其创建了 getter 和backBarButtonItemsetter setBackBarButtonItem。另请注意,该backBarButtonItem属性是在UINavigationItem类中定义的,而不是从超类继承的,因此在这种情况下,它与覆盖无关。

人们可能认为将方法转换为计算属性可以解决问题。但它没有,出于上面提到的相同原因:backBarButtonItem属性不是继承的,它是在同一个类中定义的。

很明显,现在 Xcode 6.3 修复了差异,您想要做的事情是不可能的。

为了证明这一点,如果您尝试将该扩展添加到继承自的类中UINavigationItem,它会起作用:

class MyNavigationItem : UINavigationItem {
}

extension MyNavigationItem {
    override var backBarButtonItem: UIBarButtonItem? {
        get {
            return UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
        }
        set {
            super.backBarButtonItem = newValue
        }
    }
}

请注意,您不能再创建方法,因为它会覆盖属性 getter(现在不允许这样做)。您必须覆盖整个属性,使其成为计算属性。

于 2015-04-17T07:08:00.317 回答
0

从错误消息看来,它backBarButtonItem是一个属性,而不是方法UINavigationItem。事实上,我只是证实了这一点。

var backBarButtonItem: UIBarButtonItem?

因此,您试图通过将属性声明为扩展中的方法来覆盖该属性。据我所知,您只能将计算属性(实例或类型)添加到扩展中,因此尝试backBarButtonItem在扩展中覆盖将不起作用。

于 2015-04-16T23:01:13.000 回答