在实现类型

时间:2016-09-10 19:26:50

标签: swift swift3

假设我有一个带有bar()方法的协议,该方法具有默认实现 - 本质上是Swift方式,可以为实现类型提供可选的协议要求:

protocol Foo {
    func bar()
}

extension Foo {
    func bar() {
        print("default bar() implementaion")
    }
}

现在假设我决定重命名该方法barrrr(),因为更多r更好:

protocol Foo {
    func barrrr()
}

extension Foo {
    func barrrr() {
        print("default barrrr() implementaion")
    }
}

现有代码仍然可以使用旧名称实现该方法:

class Thinger: Foo {
    func bar() {
        print("custom bar() implementaion")
    }
}

此代码认为它正在自定义Foo方法,但事实并非如此。呼叫者将查找barrrr(),并获得默认实现。没有人打电话给bar()

因此,我想为实现Foo并具有bar()方法的类型生成警告。这不起作用:

protocol Foo {
    func barrrr()

    @available(*, deprecated: 0.99, renamed: "barrrr()")
    func bar()
}

extension Foo {
    func barrrr() {
        print("default barrrr() implementaion")
    }

    func bar() {
        fatalError("renamed barrrr()")
    }
}

class Thinger: Foo {
    func bar() {   // No warning here!
        print("custom bar() implementaion")
    }
}

制作扩展方法final无效。有办法吗?它不一定是一个友好的警告;任何编译器错误就足够了。

2 个答案:

答案 0 :(得分:1)

如果我正确理解了这个问题,我不相信有办法做到这一点 - 也不应该这样做。

你有一个协议,我们称之为MyProtocol ...

protocol MyProtocol {
    func myOldFunction()
}

extension MyProtocol {
    func myOldFunction() {
        print("doing my old things")
    }
}

在以后的版本中,您希望在协议中重命名一个函数。

protocol MyProtocol {
    func myOldFunction() // now deprecated
    func myNewFunction()
}

在符合MyProtocol和已实现myOldFunction()的任何类上抛出弃用警告的主要问题是,实现 not的函数和属性的类没有任何问题 您的协议的一部分。

这些方法或属性可能仍然是其他不关心您的协议的完全有效的实现。

请注意,没有什么能阻止我们这样做:

protocol ViewControllerDeprecations {
    func viewDidLoad() // mark deprecated
    func viewWillAppear(Bool) // mark deprecated
    // etc., for all the life cycle methods
}

extension UIViewController: ViewControllerDeprecations {}

现在,包含具有上述代码的文件的任何应用程序中的每个UIViewController子类都包含这些愚蠢的弃用警告,因为您的特定协议不再使用这些方法。< / p>

答案 1 :(得分:1)

正如another answer所建议的那样,如果没有关于它是否是一件好事的立场,至少在Swift 3中,你所要求的确切是不可能的。

但是,正如我指出in response to a related question,可以弃用整个协议,这样做至少会在实现类型级别给出弃用警告,如果不是精确地在所需的属性/方法级别