通过这个简单的类,我得到了编译器警告
试图在自己的setter/getter中修改/访问x
当我这样使用它时:
var p: point = Point()
p.x = 12
我得到一个EXC_BAD_ACCESS。我怎么能做到这一点没有显式支持变量?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
详细解释一下GoZoner的回答:
这里真正的问题是递归地调用getter。
var x:Int
{
set
{
x = newValue * 2 // This isn't a problem
}
get {
return x / 2 // Here is your real issue, you are recursively calling
// your x property's getter
}
}
就像上面的代码注释建议的那样,你无限地调用x属性的getter,它将继续执行,直到你得到一个EXC_BAD_ACCESS代码(你可以在你的Xcode的游乐场环境的右下角看到旋转器)。
请看Swift文档中的例子:
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
注意,center computed属性在变量的声明中从不修改或返回自身。
你用x递归地定义x,就好像有人问你多大了?你回答"我的年龄是我的两倍"这毫无意义。
你必须说我的年龄是约翰的两倍或者其他变量,除了你。
计算变量总是依赖于另一个变量。
经验法则是永远不要从getter (get)中访问属性本身。因为这会引发另一个get,而这个get又会引发另一个get…甚至不要打印出来。因为打印也需要在打印之前“获取”值!
struct Person{
var name: String{
get{
print(name) // DON'T do this!!!!
return "as"
}
set{
}
}
}
let p1 = Person()
因为这将给出以下警告:
试图从它自己的getter中访问'name'。
错误看起来像这样模糊:
作为替代,你可能想要使用didSet。使用didSet,你会得到一个值,这个值是之前设置的,刚刚设置的。更多信息请看这个答案。