符合协议并保持私有财产

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了符合协议并保持私有财产相关的知识,希望对你有一定的参考价值。

我需要在一致的类中使用协议属性作为私有。但是编译器拒绝这样做。我该如何实现呢?

protocol ProtocolX: class {
    var x: Int { get set }

    func performAnyActionOnX()
}

extension ProtocolX {
    func performAnyActionOnX() {
        x = 5
        print(x)
    }
}

class A: ProtocolX {
    private var x:Int = 7
}

谢谢。

答案

根据@ TheAppMentor评论中所述的原因,没有针对您的问题的确切解决方案。但是,如果您的目的是让您的代码可以理解为人类(而不是欺骗编译器),那么可能会有一些解决方法。

在Swift 4.0中编译。

解决方案1:类似Python的__privacy

快速而简单。此解决方案依赖于同意从_开始的属性和函数是私有且不应被访问的用户。

protocol ProtocolX: class {
    // Public x
    var x: Int { get }

    // It's private!
    var _x: Int { get set }

    func performAnyActionOnX()
}

extension ProtocolX {
    var x: Int { return _x }

    func performAnyActionOnX(){
        _x = 5
        print(x)
    }
}

class A: ProtocolX {
    var _x: Int = 7
}

解决方案2:附加的抽象层

建筑上正确。您应该将协议拆分为两部分:私有和公共。

protocol ProtocolX: class {
    var x: Int { get }

    func performAnyActionOnX()
}

protocol ProtocolXImplementation: class {
    var _x: Int { get set }
}

extension ProtocolXImplementation {    
    var x: Int { return _x }

    func performAnyActionOnX(){
        _x = 5
        print(x)
    }
}

class A: ProtocolX, ProtocolXImplementation {
    var _x: Int = 7
}

// ... somewhere later ...
// Hide the implementation when use `A`:
let item: ProtocolX = A()
另一答案

正如@TheAppMentor所提到的,从Swift 4开始,似乎没有解决这个问题的确切方法。

但是,有两个近似的解决方案:

1.)

由于Swift中的协议默认具有internal的访问级别,因此将变量设为internal。为了使编译器强制执行internal,请将协议,类及其所有使用者(用户)移动到单独的模块(框架)。

/* internal */ protocol ProtocolX: class {
    var x: Any { get set }

    func performAnyActionOnX()
}

extension ProtocolX {
    func performAnyActionOnX() {}
}

/* internal */ class A: ProtocolX {
    internal var x: Any = 0
}

2.)

为协议提供private的访问级别和变量fileprivate的访问级别。为了能够访问private协议,请将协议,类及其所有使用者移动到同一源文件中。

private protocol ProtocolX: class {
    var x: Any { get set }

    func performAnyActionOnX()
}

extension ProtocolX {
    func performAnyActionOnX() {}
}

class A: ProtocolX {
    fileprivate var x: Any = 0
}

以上是关于符合协议并保持私有财产的主要内容,如果未能解决你的问题,请参考以下文章

访问受保护或私有财产

OCUnit 在私有财产上

理解Marx-11 私有财产的争论

Objective-C如何声明类别的私有财产?

家庭财产房屋分配协议书

如何管理在每个 git 版本中添加私有代码片段?