通过这个简单的类,我得到了编译器警告
试图在自己的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
}
}
// ...
}
你用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,你会得到一个值,这个值是之前设置的,刚刚设置的。更多信息请看这个答案。
setter和getter应用于计算属性;这样的属性在实例中没有存储空间——getter中的值将从其他实例属性中计算出来。在你的例子中,没有x被赋值。
显式地:“在没有显式支持ivars的情况下如何做到这一点”。您不能这样做—您需要备份计算的属性。试试这个:
class Point {
private var _x: Int = 0 // _x -> backingX
var x: Int {
set { _x = 2 * newValue }
get { return _x / 2 }
}
}
具体来说,在Swift REPL中:
15> var pt = Point()
pt: Point = {
_x = 0
}
16> pt.x = 10
17> pt
$R3: Point = {
_x = 20
}
18> pt.x
$R4: Int = 10