快速提问:为什么?
背景:
使用Swinject依赖注入将 small-s 单例模型类添加到我的视图中:
defaultContainer.registerForStoryboard( MyViewController.self )
{
responder, viewController in
viewController.proxy = responder.resolve( MyProxy.self )!
}
我想通过使用计算属性来防止意外覆盖此单例实例的风险:
private var _proxy: MyProxy!
var proxy: MyProxy
{
set { if _proxy == nil { _proxy = newValue } }
}
但是。我不能。因为我必须也宣布一个吸气剂。
令人沮丧!
目前我正在使用以下黑客攻击。但是真的......
var proxy: MyProxy?
{
get { return nil }
set { if _proxy == nil && newValue != nil { _proxy = newValue } }
}
答案 0 :(得分:8)
将get
(或set
)添加到属性后,它会变为Computed Property。计算属性可能只读,因此只需要get
ter ,但它们可能不是只写的。因此,如果您向属性添加set
ter ,则将其转换为计算机属性,因此必须添加getter。
编辑:在评论之后, 为什么计算属性只能是只读的,而不是只写的?
我找不到官方文档来支持这一点,所以以下解释完全基于我的逻辑观点:
计算属性不会在变量上存储实际数据;相反,他们计算要显示的数据。
var a:Int = 5 // Stored property
var timesTen:Int { // Computed Property
get {
return a * 10
}
}
从上面的示例中:a
是存储的属性。因此,其get
方法会自动返回a
的值。现在想起timesTen
:它有什么价值?由于它不会在timesTen
变量中存储任何值,因此必须告知计算属性从读取其“值”的方式和位置。这就是为什么你不能将计算属性用于只写目的。
对于简单属性,您可以使用didSet
或willSet
来达到预期目的:
var proxy: MyProxy?
{
willSet { if _proxy == nil && newValue != nil { _proxy = newValue } }
}
如果您使用的是Swift 2.x,可以使用guard
语句获取更清晰的代码:
var proxy: MyProxy?
{
willSet {
guard (_proxy == nil && newValue != nil) else { return }
_proxy = newValue
}
}
如果_proxy
不是必需为private
,您可以完全删除它,只使用一个变量/属性而不是两个:
var proxy: MyProxy!
{
willSet {
guard (proxy == nil && newValue != nil) else { return }
// By not preventing `willSet` to continue, `newValue` will automatically assigned to `proxy`
}
}
答案 1 :(得分:1)
为什么你不能在你的吸气器中返回_proxy
?那有什么关系?如果您害怕暴露您的getter,您可以将getter设置为private,从而仅在包含类中公开它。
private(get) var proxy: MyProxy? {
set { if _proxy == nil && newValue != nil { _proxy = newValue } }
}
答案 2 :(得分:0)
目前,您只能使用属性观察者didSet
或willSet