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

试图在自己的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
        }
    }
    // ...
}

当前回答

Swift中的setter和getter适用于计算的属性/变量。这些属性/变量实际上并不存储在内存中,而是根据存储的属性/变量的值计算出来的。

请参阅Apple的Swift文档:Swift变量声明。

其他回答

Swift中的setter /getter与ObjC有很大不同。属性变成一个计算属性,这意味着它不像在ObjC中那样有一个支持变量,比如_x。

在下面的解决方案代码中,您可以看到xTimesTwo不存储任何东西,而是简单地计算x的结果。

请参阅有关计算属性的官方文档。

您想要的功能也可能是Property observer。

你需要的是:

var x: Int

var xTimesTwo: Int {
    set {
       x = newValue / 2
    }
    get {
        return x * 2
    }
}

您可以在setter/getter中修改其他属性,这就是它们的意义所在。

更新: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

为了覆盖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

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

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

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