【问题标题】:Swift Extension - method conflicts with previous declaration with the same Objective-C selectorSwift 扩展 - 方法与具有相同 Objective-C 选择器的先前声明冲突
【发布时间】:2016-06-08 15:32:58
【问题描述】:

我正在开发具有 Obj C 代码和 Swift 的 iOS 应用程序。我正在将现有的 Objective C 类别迁移到 swift 代码。但是当我在 swift 扩展中覆盖现有方法时,它不会编译。 Swift 扩展适用于新方法,但不适用于覆盖现有方法。

代码:

extension UIViewController {


   public override func shouldAutorotate() -> Bool {
        return false
    }

    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }


}

错误:

 Method 'shouldAutorotate()' with Objective-C selector 'shouldAutorotate' conflicts with previous declaration with the same Objective-C selector

 Method does not override any method from its superclass

 Method 'supportedInterfaceOrientations()' with Objective-C selector 'supportedInterfaceOrientations' conflicts with previous declaration with the same Objective-C selector

在这里,我错过了什么吗?

我正在使用Xcode 7.3.1Swift 2.x

编辑:

从下面的答案中,我知道我们不能像在 Objective C 类别中那样在 Swift 扩展中更改现有类方法在运行时的行为。在这里,我应该创建一个将覆盖方法的基类,并且我应该使用我所有的 ViewControllers 作为新基类中的子类作为父类。

但就我而言,我想更改所有“shouldAutorotate”方法的行为,包括第 3 方框架 UIViewController。在上述情况下,我不能强制所有第三方框架 UIviewControllers 成为我的基类的子类。在Objective C中我可以做到这一点。

【问题讨论】:

    标签: ios objective-c swift swift2


    【解决方案1】:

    Swift 扩展不能用于覆盖在它们扩展的类中声明的方法——尤其是对于 Objective-C 类,这非常类似于在同一个类中提供同一方法的两个定义。想象一下看到一个看起来像这样的类:

    class UIViewController : UIResponder {
        public func shouldAutorotate() -> Bool {
            return true
        }
        public func shouldAutorotate() -> Bool {
            return false
        }
    }
    

    谁赢了?这就是你被警告的冲突。

    如果您需要覆盖您的视图控制器的方法,您需要在 子类 中进行,而不是在扩展中。

    Ninja 编辑: 这在 Objective-C 中可能是可以做到的,但那里是一个编程错误。如果一个类别从主类复制了一个方法,那么使用哪个定义是未定义的。请参阅this SO postbacking Apple documentation

    【讨论】:

    • 所以在这种情况下,在 swift 扩展中。如果没有子类化,我们将无法在运行时更改现有类方法的行为?
    • 正确 - 如果您想以这种方式更改类的行为,请将其子类化。例如,这可以防止您的代码影响 Apple 正在使用的任何 UIViewController 实例。
    • 那我们应该如何快速实现呢?我想更改所有“shouldAutorotate”方法的行为,包括 3rd 方框架 UIViewController。在上述情况下,我不能强制所有第三方框架 UIviewControllers 成为我的基类的子类。在 Objective C 中,我可以做到这一点。
    • 在问题中更新
    • 简短的回答是您不应该这样做。 Apple 和第三方框架可能对如何为其控制器实现方法(包括shouldAutorotate)有自己的特定概念,覆盖它们通常不是一个好主意。您是否正在尝试解决潜在的问题?例如,如果您需要关闭整个应用的旋转,可以通过在项目的 settings/Info.plist 文件中限制方向支持来实现。
    猜你喜欢
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 2012-05-09
    相关资源
    最近更新 更多