2014-06-05 54 views
0

的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可能被使用的唯一方式。

+1

你可能談論shape'和'origin'的'一些特定的情況下,由於實際上這個結構:'object.subobject.x = 50;'只要'x'有一個setter('x'不是隻讀的)就可以正常運行。 – FreeNickname

回答

3

房產觀察員(willSetdidSet火災時子 - 屬性的屬性被改變。在這種情況下,當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)! 
+0

這正是我在回答中的含義。如果操作系統確實嘗試了它並且對他不起作用,他就會遇到一些編譯器錯誤。 –

+0

這個工程,我意外地輸入類Point而不是struct Point。 – Senseful

1

這不工作?

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

編輯:重新訪問代碼並添加參數名稱以反映期望的內容。

+0

它應該工作。如果它不是它的一些錯誤。 'Point'是一個結構,結構是值類型。因此(模優化),只要其中一個字段發生更改,它們就會被完全複製/重新分配。 –

+0

在類的聲明之後是否有使用'()'的原因?我沒有看到這個,只是好奇,如果有什麼我從Swift語言中缺少的東西。 (我注意到OP也這樣做) – Erik

+0

因爲我很懶,做了OP代碼的剪切和粘貼。現在編輯(不在家,不能測試代碼,所以我正在寫內存)。 –

-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 
+0

請參閱更新 – Senseful

0

您可以使用屬性的觀察員也適用於結構

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 
+0

此作品,謝謝。如果你編輯你的帖子,我可以反轉我的投票。 – Senseful