iOS Swift4如何保护接口中定义的计算属性不被赋值?

Posted

技术标签:

【中文标题】iOS Swift4如何保护接口中定义的计算属性不被赋值?【英文标题】:iOS Swift4 how to protect computed property defined in interface from assignment? 【发布时间】:2019-02-01 07:31:25 【问题描述】:

我正在为我继承的遗留代码库中的一个类调试一些编写不佳的单元测试。我看到开发人员没有正确测试计算属性。我想了解如何强制我的userEnabledFeature 在 Fake 类中只读。

为什么具有计算属性的类实现协议可以覆盖计算属性并使其可写?

public protocol FeatureManager 
    var userEnabledFeature : Bool  get 


public class FakeFeatureManagerForTesting: FeatureManager 
    public var userEnabledFeature = false //is this legal? Why is compiler not complaining?

    public func updateUserEnabledFeature(enabled: Bool)
        //this should not be possible - how do I prevent overwriting computed property?
        userEnabledFeature = enabled
    


ActualFeatureManagerClass 
    public var userEnabledFeature: Bool 
        if featureManager.cachedFeatures.filter  $0.enabled == true
        
            //do more checks, return true or false
        
        return false //default
    

【问题讨论】:

FakeFeatureManagerForTesting中的属性改为:public var userEnabledFeature: Bool return false 【参考方案1】:
public class FakeFeatureManagerForTesting: FeatureManager 
  public var userEnabledFeature = false //is this legal? Why is compiler not complaining?

协议是说符合它的成员必须有一个可以读取的Bool 属性userEnabledFeature,而不是只读属性。但是,如果您有一个以协议为类型的变量,则即使该变量的值是 implementation 也可以写,它也不允许您分配属性。

协议没有定义它是如何实现的(如果它的计算属性、存储属性等),但它的签名是什么以及它应该是只读的还是必须有 也可以写访问。如果将其标记为只读,则实现仍然可以使写可写,因为在这种情况下协议并不真正关心写访问。

你可以像这样实现计算属性:

public class FakeFeatureManagerForTesting: FeatureManager 
  public var userEnabledFeature: Bool  
    // do some work here and return value or fallback to false
    return false
  

另一方面,您也可以只有私有可设置属性,只能从文件或类/结构中更改:

public class FakeFeatureManagerForTesting: FeatureManager 
  public private(set) var userEnabledFeature = false

  public func updateUserEnabledFeature(enabled: Bool) 
    userEnabledFeature = enabled // will work just fine
  


let manager = FakeFeatureManagerForTesting()
manager.updateUserEnabledFeature(enabled: true) // will work
manager.userEnabledFeature = true // won't compile, because modifying is allowed privately only

【讨论】:

以上是关于iOS Swift4如何保护接口中定义的计算属性不被赋值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Java类中定义接口属性并如何使用接口的方法

实施和测试 iOS 数据保护

ios 中 成员变量和属性的区别

如何使用 1 个函数将 2 个属性保存到核心数据(Swift4)

如何实现 AutoFill Credential Provider Extensions - iOS 11, swift4

如何在 swift4 中使用 Rxalamofire 发送 URL 请求