【问题标题】:Swift 1.2 ExtensionsSwift 1.2 扩展
【发布时间】:2015-04-16 22:30:01
【问题描述】:

我将 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 冲突

不能再使用扩展覆盖方法了吗?

【问题讨论】:

标签: swift xcode6.3 swift-extensions


【解决方案1】:

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

首先要说的是 6.3 中发生了一些变化(见release notes (18391046, 18383574):

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

也就是说,您正在扩展中创建一个新的 backBarButtonItem 方法。但是UINavigationItem 已经有一个backBarButtonItem 属性,并且会自动为其创建getter 和setter,分别为backBarButtonItemsetBackBarButtonItem。还要注意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(现在不允许这样做)。您必须覆盖整个属性,使其成为计算属性。

【讨论】:

    【解决方案2】:

    从错误消息看来,backBarButtonItemUINavigationItem 的属性,而不是方法。事实上,我只是验证了是这样的。

    var backBarButtonItem: UIBarButtonItem?
    

    因此,您试图通过在扩展程序中将其声明为 方法 来覆盖 属性。据我记得,您只能将 computed 属性(实例或类型)添加到扩展中,因此尝试在扩展中覆盖 backBarButtonItem 将不起作用。

    【讨论】:

    • 感谢您的回复。上面的代码在 Swift 1.1/XCode 6.2 中运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多