财产获得者和制定者
有了这个简单的类,我得到的编译器警告“试图修改/访问'在自己的setter / getter”x“,当我这样使用它:
var p: point = Point() px = 12
我得到一个EXC_BAD_ACCESS。 我怎样才能做到这一点没有明确的支持ivars?
class Point { var x: Int { set { x = newValue * 2 //Error } get { return x / 2 //Error } } // ... }
Setters和Getters适用于computed properties
; 这样的属性在实例中没有存储 – 来自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
编辑 :由于这个答案越来越upvotes,我想澄清,在Swift中的setter / getters是比ObjC完全不同。 该属性成为一个计算属性 ,这意味着它没有一个支持variables,如_x
就像在ObjC中那样。 在下面的解决scheme代码中,您可以看到xTimesTwo
不存储任何内容,只是计算 x
的结果。
请参阅关于计算属性的官方文档 。
你想要的function也可能是属性观察者 。
Setter / getters与Objective-C中的不同。
你需要的是:
var x:Int var xTimesTwo:Int { set { x = newValue / 2 } get { return x * 2 } }
您可以修改setter / getters中的其他属性,这是他们的意思。
您可以使用属性观察器自定义设置值。 为此,请使用“didSet”而不是“set”。
class point { var x:Int { didSet { x = x * 2 } } ...
至于吸气…
class point { var doubleX:Int { get { return x / 2 } } ...
详细说明GoZoner的回答:
你真正的问题在于你recursion地调用你的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游戏场环境右下angular的微调)。
考虑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) } } }
请注意,中心计算属性在variables的声明中永远不会修改或返回自身。
为了覆盖swiftvariables的setter
和getter
,使用下面给出的代码
var temX : Int? var x: Int?{ set(newX){ temX = newX } get{ return temX } }
我们需要把variables的值保存在一个临时variables中,因为试图访问同一个被getter / setter覆盖的variables会导致无限循环。
我们可以像这样调用setter
x = 10
在给定的代码行下方调用getter
var newVar = x
尝试使用这个:
var x:Int! var xTimesTwo:Int { get { return x * 2 } set { x = newValue / 2 } }
这基本上是Jack Wu的回答,但不同的是,在Jack Wu的回答中,他的xvariables是var x: Int
,在我的xvariables中是这样的: var x: Int!
,所以我所做的只是使其成为可选types。
你recursion地用x
定义x
。 好像有人问你你多大了? 而你回答“我是我的两倍”。 这是没有意义的。
你必须说我是John的两倍或者其他变数, 但是你自己。
计算的variables总是依赖于另一个variables。
Swift中的Setter和getter适用于计算的属性/variables。 这些属性/variables实际上并不存储在内存中,而是根据存储的属性/variables的值来计算的。
关于这个主题,请参阅Apple的Swift文档: Swiftvariables声明 。
更新:Swift 4
在下面的类中,setter和getter被应用于variablessideLength
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 { //setter sideLength = newValue / 4.0 } }
创build对象
var triangle = Triangle(sideLength: 3.9, name: "a triangle")
消气
print(triangle.perimeter) // invoking getter
二传手
triangle.perimeter = 9.9 // invoking setter