ios Swift 编程:存储属性中的 getter/setter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24114732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift Programming: getter/setter in stored property
提问by bohanl
How do I overwrite the setter of stored property in Swift?
如何覆盖 Swift 中存储属性的设置器?
In Obj-C, I can overwrite its setter, but Swift doesn't seem to be happy about getter/setters being used for stored property.
在 Obj-C 中,我可以覆盖它的 setter,但 Swift 似乎对用于存储属性的 getter/setter 并不满意。
Say I have a Card
class with a property called rank
. I don't want the client to give it any invalid value, therefore, in objective-C, I can overwrite setRank
so that it performs additional check. But willSet
in Swift doesn't seem to help because newValue
is constant and it makes no sense to assign rank
because setter will be called in a loop.
假设我有一个Card
名为rank
. 我不希望客户端给它任何无效的值,因此,在 Objective-C 中,我可以覆盖setRank
以便它执行额外的检查。但是willSet
在 Swift 中似乎没有帮助,因为newValue
它是常量并且分配没有意义,rank
因为 setter 将在循环中被调用。
回答by Mihai Fratu
Ok. Reading through Apples documentation on Swift I found this:
好的。阅读有关 Swift 的 Apples 文档,我发现了这一点:
If you assign a value to a property within its own didSet observer, the new value that you assign will replace the one that was just set.
如果你在它自己的 didSet 观察者中为一个属性赋值,你分配的新值将替换刚刚设置的值。
So all you have to do is this:
所以你所要做的就是:
var rank: Int = 0 {
didSet {
// Say 1000 is not good for you and 999 is the maximum you want to be stored there
if rank >= 1000 {
rank = 999
}
}
}
回答by Joseph Mark
You can't override get
/set
for a stored property but you can use property observers willSet
/didSet
:
您不能为存储的属性覆盖get
/ set
,但可以使用属性观察者willSet
/ didSet
:
var totalSteps: Int = 0 {
willSet(newTotalSteps) {
println("About to set totalSteps to \(newTotalSteps)")
}
didSet {
if totalSteps > oldValue {
println("Added \(totalSteps - oldValue) steps")
}
}
}
The default parameter names are newValue
for willSet
and oldValue
for didSet
, or you can name them yourself as in willSet(newTotalSteps)
.
默认参数名称为newValue
forwillSet
和oldValue
for didSet
,或者您可以自己将它们命名为 in willSet(newTotalSteps)
。
回答by user3675131
get and set are for computed properties (they don't have any backing store). (In my opinion, the keyword 'var' is confusing here)
get 和 set 用于计算属性(它们没有任何后备存储)。(在我看来,关键字“var”在这里令人困惑)
- willSet and didSet are called for an instance variable (Use didSet to override any changes)
- set and get are purely for computed properties
- 为实例变量调用 willSet 和 didSet(使用 didSet 覆盖任何更改)
- set 和 get 纯粹用于计算属性
回答by Jim Driscoll
If you don't want to use didSet, which has the problem that the property's value is temporarily wrong, you should wrap a computed property around it.
如果你不想使用 didSet,它有属性值暂时错误的问题,你应该在它周围包裹一个计算属性。
private var _foo:Int = 0
var foo:Int {
get {
return _foo
}
set {
if(newValue > 999) {
_foo = 999
} else {
_foo = newValue
}
}
}
Or:
或者:
private var _foo:Int = 0
var foo:Int {
get {
return _foo
}
set {
guard newValue <= 999 else {
_foo = 999
return
}
_foo = newValue
}
}
回答by Mike Rapadas
Simplified Example:
简化示例:
class Shape {
var sideLength: Double {
get {
return self.sideLength
}
set {
// Implement the setter here.
self.sideLength = newValue
}
}
}
Full example
完整示例
Check out perimeter
in this example.
perimeter
在这个例子中查看。
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
摘自:Apple Inc. “The Swift Programming Language”。电子书。https://itun.es/us/jEUH0.l
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triagle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength”