通过这个简单的类,我得到了编译器警告

试图在自己的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,你会得到一个值,这个值是之前设置的,刚刚设置的。更多信息请看这个答案。

其他回答

更新:Swift 4

在下面的类setter和getter应用于变量sideLength

class Triangle: {
    var sideLength: Double = 0.0

    init(sideLength: Double, name: String) { //initializer method
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }

    var perimeter: Double {
        get { // getter
            return 3.0 * sideLength
        }
        set(newValue) { //setter
            sideLength = newValue / 4.0
        }
   }

创建对象

var triangle = Triangle(sideLength: 3.9, name: "a triangle")

Getter

print(triangle.perimeter) // invoking getter

triangle.perimeter = 9.9 // invoking setter

你用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,你会得到一个值,这个值是之前设置的,刚刚设置的。更多信息请看这个答案。

这里有一个理论上的答案。可以在这里找到

{get set}属性不能是常量存储属性。它应该是一个计算属性,get和set都应该被实现。

为了覆盖swift变量的setter和getter,请使用下面给出的代码

var temX : Int? 
var x: Int?{

    set(newX){
       temX = newX
    }

    get{
        return temX
    }
}

我们需要将变量的值保存在临时变量中,因为试图访问其getter/setter被重写的相同变量将导致无限循环。

我们可以像这样简单地调用setter

x = 10

Getter将在给定代码行以下触发时调用

var newVar = x

您可以使用属性观察者自定义设置值。要做到这一点,使用'didSet'而不是'set'。

class Point {

var x: Int {
    didSet {
        x = x * 2
    }
}
...

至于getter…

class Point {

var doubleX: Int {
    get {
        return x / 2
    }
}
...