【问题标题】:Swift access control on protocol conformance对协议一致性的快速访问控制
【发布时间】:2015-12-28 20:44:46
【问题描述】:

我在如下文件中定义了一个私有协议

private protocol testProtocol {
 func testFunc1()
 func testFunc2()
}

一个公共类符合上述协议如下

 public class testClass : testProtocol {
 func testFunc1() {}
 func testFunc2() {}
}

根据苹果文档,公共类的成员默认获得内部访问控制,除非它被显式设置为不同的访问控制修饰符。

文档还说,类型对具有较低访问控制的协议的一致性将使该类型对协议访问控制的实现与协议的实现相同。在这种情况下,由于类型的访问控制是公共的,而协议的访问控制是私有的,因此 testfunc1 和 testfunc2 方法应该获得私有的访问控制。

当类在不同的源文件中实例化并且方法如下访问时,编译器不会显示不期望的错误,因为根据指南,方法应该是私有的

var test: testClass = testClass()
test.testFunc1()

这是预期的行为吗?我错过了什么吗?

【问题讨论】:

  • 你找到解决办法了吗?

标签: ios protocols swift2 access-control


【解决方案1】:

Apple Documentation 说:

当您编写或扩展一个类型以符合协议时,您必须确保该类型对每个协议要求的实现至少具有与该类型对该协议的符合性相同的访问级别。

据此,我假设在 testClass 中使用另一个访问控制修饰符实现方法 testFunc1 和 testFunc2 只会覆盖协议中的那个。如果您使用此方法的默认协议实现,如以下编译器将返回错误:

extension testProtocol {
    func testFunc1() {}
    func testFunc2() {}
}

就 Swift 是用协议替换继承的面向协议的语言而言,如果您想在自定义类中更改协议定义的函数访问级别,这可能是合理的。

【讨论】:

    【解决方案2】:

    根据 Apple 的文档:

    当您编写或扩展一个类型以符合协议时,您必须确保 > 每个协议要求的类型实现具有至少与该类型对该协议的符合性具有相同的 > 访问级别.

    请注意文档中的“至少”,表示只要该类型的实现协议要求的访问级别高于或等于 协议的访问级别,就可以了。在您的情况下, testClass 中的 testFunc1 和 testFunc2 的默认访问级别为 internal,它高于 private 的访问级别。所以实际上testClass中的两个方法都获得了internal的访问级别,编译器不会把它当作en error。

    我们可以对您的代码稍作修改,如下所示:

        fileprivate protocol TestProtocol {
            func testFunc1()
            func testFunc2()
        }
    
        public class TestClass : TestProtocol {
            public func testFunc1() {}
            public func testFunc2() {}
       }
    

    这段代码也能正常编译。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      相关资源
      最近更新 更多