检测复合属性的变化

时间:2014-06-05 06:04:03

标签: properties swift observable

Objective-C不允许您运行以下代码:

myShape.origin.x = 50

这使得检测原点的变化变得容易,因为使用你的类的人被迫写myShape.origin = newOrigin,因此你可以轻松地绑定到这个属性的setter。

Swift现在允许您执行原始的,以前不允许的代码。假设有以下类结构,您如何检测对原点的更改以执行您自己的代码(例如更新屏幕)?

struct Point {
    var x = 0
    var y = 0
}

class Shape {
    var origin: Point = Point()
}

更新:也许我应该更明确,但假设我不想修改Point结构。原因是Shape只是一个使用Point的类,可能还有数百个其他类,更不用说原点不是Point可以使用的唯一方式。

4 个答案:

答案 0 :(得分:3)

当属性的子属性发生更改时,属性观察者(willSetdidSet执行会触发。在这种情况下,当x结构的y Point值发生更改时,将设置该属性。

这是我的示例游乐场代码:

struct Point : Printable 
{
    var x = 0
    var y = 0

    var description : String {
    {
        return "(\(x), \(y))";
    }
}

class Shape
{
    var origin : Point = Point()
    {
        willSet(newOrigin)
        {
            println("Changing origin to \(newOrigin.description)!")
        }
    }
}

let circle = Shape()

circle.origin.x = 42
circle.origin.y = 77

这是控制台输出:

Changing origin to (42, 0)!
Changing origin to (42, 77)!

答案 1 :(得分:1)

这不起作用吗?

class Shape {
   var origin: Point {
   willSet(aNewValueForOrigin) {
       // pre flight code
   }
   didSet(theOldValueOfOrigin) {
       // post flight code
   }
   }
}

编辑:重新访问的代码和添加的参数名称,以反映期望的内容。

答案 2 :(得分:0)

您可以使用Property Observers也适用于结构

Link to the part on the ebook

class StepCounter {
    var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        println("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        if totalSteps > oldValue  {
            println("Added \(totalSteps - oldValue) steps")
        }
    }
    }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps
stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps
stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps

答案 3 :(得分:-1)

使用didSet,例如,

struct Point {
    var x = 0
    var y: Int = 0 {
    didSet {
        println("blah blah")
    }
    }
}

class Shape {
    var origin: Point = Point()
}

let s = Shape()

s.origin.y = 2