当某些协议功能改变其签名时,我可以强制编译器失败吗?

时间:2017-11-27 22:12:18

标签: swift xcode protocol-extension

有没有办法将某些Swift函数标记为实现某些协议函数,以便在协议的签名发生更改时,编译器可以将实现标记为错误。

例如,考虑这个示例,其中 private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e) { if (e.TabPageIndex > 0 /* && some condition still not reached */) { e.Cancel = true; } //Avoiding a tabchange from Index Zero if some condition is not accomplished yet //e.TabPageIndex: is the new TabIndex //e.Cancel == true: makes the TabControl stay in the previous tab index } 实例的Foo协议的默认实现,我想为一个子类的自定义UIViewController类重写它Bar

UIViewController

现在,该协议演变为:

// V1
protocol Foo {
    func number() -> Int
}

extension Foo where Self: UIViewController {
    func number() -> Int {
        return 0
    } 
}

// Overrides the default implementation
extension Bar: Foo {
    func number() -> Int {
        return 1
    }
}

如何帮助我的// V2 protocol Foo { func numberV2() -> Int } extension Foo where Self: UIViewController { func numberV2() -> Int { return 0 } } // I think I override the default implementation but not anymore. // => error prone, no error from the compiler extension Bar: Foo { func number() -> Int { return 1 } } 分机了解Bar功能与number协议不再相关?

2 个答案:

答案 0 :(得分:2)

如果功能被覆盖,这是默认协议实现应尽可能具体的原因之一。

如前所述,没有直接的方法可以做到这一点,但我会给你一些解决方法。

  • 有2个协议,一个具有默认实现,另一个没有。例如AutoFoo: FooFoo。拥有AutoFoo上的默认实施,并且只有Foo才能使用Bar,以免受AutoFoo默认实施的影响。
  • 更改名称时使用重构引擎(内置的Xcode引擎应该工作)
  • 更改协议中的名称,构建,然后找到所有有错误的地方。

答案 1 :(得分:0)

您可以改为提供一个UIViewController根类来实现您的UIViewController协议,并为所有其他类使用子类,而不是定义管理Foo类型对象的协议扩展。 UIViewController需要实施Foo

用代码解释:

您的Foo协议:

protocol Foo {
    func number() -> Int
}

以下是Root类的外观:

class Root: UIViewController, Foo {
    func number() -> Int {
        return 1
    }
}

你的子类的重写实现:

class Bar: Root {
    override func number() -> Int {
        return 5
    }
}

每次更改Foo协议的方法签名时,编译器都会针对Root类抛出错误,因为它不再符合Foo协议并且不符合Bar子类(一旦修复了此错误),因为它不会覆盖Root的任何方法。

对于您不需要覆盖Foo的类,您可以继承Root并使用默认实现:

class Joe: Root {
}

完整代码(之前):

protocol Foo {
    func number() -> Int
}

extension Foo where Self: UIViewController {
    func number() -> Int {
        return 0
    }
}

// Class with an overrided implementation of the number() method.
class Bar: UIViewController, Foo {
  func number() -> Int {
      return 1
  }
}

// Class uses the default implementation of the number() method.
class Joe: UIViewController, Foo {

}

完整代码(之后):

protocol Foo {
    func number() -> Int
}

class Root: UIViewController, Foo {
    func number() -> Int {
        return 1
    }
}

// Class with an overrided implementation of the number() method.
class Bar: Root {
    override func number() -> Int {
        return 5
    }
}

// Class uses the default implementation of the number() method.
class Joe: Root {
}

希望它有所帮助。