在Swift中如何覆盖私有方法并调用super?

8

我们知道,如果你需要在Swift中覆盖父类的方法,你必须在该方法之前声明"override"关键字。如果该方法是私有的,你仍然可以在Swift中覆盖它,只需不添加override关键字即可。但是,你无法调用super.MethodName(),这是我的问题。

比如说,在UINavigationController中有一个名为"_startCustomTransition"的私有方法,我可以在自定义的MyNavigationController.swift中做到这一点。

class MyNavigationController: UINavigationController {
    func _startCustomTransition() {
        // I can not call super._startCustomTransition()
    }
}

那么,我该如何进行超级调用呢?谢谢。

你应该能够使用super调用performSelector: (https://dev59.com/nFgQ5IYBdhLWcg3w9Yvk),或者使用方法交换(method swizzling)(https://dev59.com/klkS5IYBdhLWcg3ws4Yk)来实现这种行为。 - Amresh
你不能调用super的原因是因为你的类MyNavigationController继承自类UINavigationController,而它在这种情况下没有一个名为_startCustomTransition()的方法。在这种情况下,使用#selector方法可能是最好的选择,正如Amresh Kumar所提到的那样。 - CarpenterBlood
2个回答

6

您需要欺骗Swift编译器,让它相信这种方法存在。为此,您可以在项目的桥接头文件中添加一个Objective-C扩展声明:

@import UIKit;

@interface UINavigationController(PrivateMethods)

- (void)_startCustomTransition;

@end

现在,您可以轻松地覆盖该方法:
class MyNavigationController: UINavigationController {
    override func _startCustomTransition() {
        super._startCustomTransition()
    }
}

编辑:您需要在Objective-C扩展中声明该方法,因为我没有看到在Swift扩展中声明该方法而不实现它的方式。欢迎提供建议。:)


为什么要费心去处理整个Objective-C的难点,不如使用Swift扩展。 - CarpenterBlood
当您可以声明一个方法而不实现它时,这应该可以使用纯Swift工作。 - clemens
它确实有效,只是我想知道为什么你用Objective C代码回答了一个Swift问题。 - CarpenterBlood
如果我的项目没有桥接头文件怎么办?这是一个纯Swift项目。也就是说,在创建项目时我选择了Swift作为项目的语言。 - ma11hew28
对不起。什么是头文件或Objective-C文件,我该如何在Xcode中创建它? - ma11hew28
显示剩余6条评论

1

2
Method does not override any method from its superclass - Itachi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接