Ios 如何使用同一类针对每个目标执行不同的功能?扩展及;协议让我失望
简单的场景:我有一个基本的ViewController,它有一个我想在子类中选择性重写的方法。我想在子类ViewController的扩展中进行覆盖 这不起作用:Ios 如何使用同一类针对每个目标执行不同的功能?扩展及;协议让我失望,ios,swift,Ios,Swift,简单的场景:我有一个基本的ViewController,它有一个我想在子类中选择性重写的方法。我想在子类ViewController的扩展中进行覆盖 这不起作用: class BaseViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() overrideStyles() } func overrideStyles() {
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
overrideStyles()
}
func overrideStyles() {
// do nothing here. Optionally overridden as needed
}
}
class ViewController: BaseViewController {
}
// this is in another file that is to a specific target
extension ViewController {
override func overrideStyles() {
print("YAY!")
}
}
它也不适用于协议:
protocol OverridesStyles {
func overrideStyles()
}
extension OverridesStyles {
func overrideStyles() {
print("default method that does nothing")
// do nothing, this makes the method optional
}
}
class BaseViewController: UIViewController, OverridesStyles {
override func viewDidLoad() {
super.viewDidLoad()
overrideStyles()
}
}
// this is in another file that is to a specific target
extension ViewController {
func overrideStyles() {
print("YAY!")
}
}
我不能对整个ViewController类进行子类化,因为它是情节提要中的类,并且我不能对每个目标使用不同的情节提要
还有别的办法吗?我的想法是,我可以有不同的目标,每个目标有不同的扩展,因为overrideStyles方法可能会根据目标引用不同的UI元素
谢谢。文档给出了答案,这是一条规则: 扩展可以向类型添加新功能,但不能覆盖现有功能 我无法解释原因,但重写子类扩展中的方法似乎只有在需要重写 基类中的方法也在扩展中定义 以下是一个独立的示例:
class A : NSObject {
override init() {
super.init()
foo()
bar()
}
func foo() {
print("foo from A called")
}
}
extension A {
func bar() {
print("bar from A called")
}
}
class B : A { }
extension B {
override func foo() {
print("foo from B called")
}
override func bar() {
print("bar from B called")
}
}
let b = B() // foo from A called, bar from B called
可以看到,从子类B
按预期调用,但基类
A
中的foo()
方法正常。。。我找到了这个问题的一个有趣的答案,它实现了我想要的。将OverrideStyles协议应用于BaseViewController将不允许我对ViewController类进行协议扩展。(好吧,它会允许的,但它不起作用)
但是,将OverrideStyles协议应用于ViewController类可以让我成功地进行协议扩展。因此,似乎不能对子类进行协议扩展,而只能对同一个类进行协议扩展
总之,这是可行的:
protocol OverridesStyles {
func overrideStyles()
}
extension OverridesStyles {
func overrideStyles() {
print("default method that does nothing")
// do nothing, this makes the method optional
}
}
class ViewController: BaseViewController, OverridesStyles {
override func viewDidLoad() {
super.viewDidLoad()
overrideStyles()
}
}
// this is in another file that is to a specific target
extension ViewController {
func overrideStyles() {
print("YAY!")
}
}
我也有同样的问题,如果我使用prototype选项,它会抱怨函数不在主类中,但是如果我将其添加到主类中作为基类,它会抱怨“无效的重新声明…”,因为它认为同一函数有两个声明 试试这个:
// Main class file
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
overrideStyles()
}
}
// In a separate file with Target set to one Target
extension TestViewController {
func overrideStyles() {
print("default method that does nothing")
// do nothing, this makes the method optional
}
}
// In another separate file with Target set to another Target
extension TestViewController {
func overrideStyles() {
print("YAY!")
}
}
我发现在为目标构建时,如果没有定义该目标的扩展,并且主视图控制器中没有提示您添加会破坏该目标的函数,那么它会很好地抱怨。这也意味着您可以在单个故事板中很好地使用TestViewController,该故事板以您希望的任何目标为目标。因此,您现在有1个故事板,其中1个大容量代码作为基础,还有一个只包含变体的函数。在我的工作版本中,这是用来更改iAction上的操作的,效果很好
@IBAction func continueTapped() {
continueAction()
}
我的想法是,我可以有不同的目标,每个目标有不同的扩展,因为overrideStyles方法可以根据目标引用不同的UI元素。为什么不呢?:class ViewController:BaseViewController{override func overrideStyles(){super.overrideStyles()//如果你想打印(“耶!”)},应该可以。@SherM4n不,我不能这样做。因为故事板中必须使用ViewController类。我不能为每个目标设置不同的故事板。@Aronbratcher我不明白为什么故事板会出现在表中,但是,基本上,如果viewcontroller继承自baseviewcontroller,则可以重写其方法并在内部执行任何您想要的操作。根据您的需要,这两个视图控制器在不同或相同的故事板中。我有一个通过故事板实例化的ViewController类。如果我想以不同的方式覆盖它,我不能子类化,因为如果我子类化,那么故事板引用需要指定新的类。