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如何保护接口中定义的计算属性不被赋值?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 1 个函数将 2 个属性保存到核心数据(Swift4)
如何实现 AutoFill Credential Provider Extensions - iOS 11, swift4