[英]Why is 'didset' called on a property when I set the property of that property?
在此代碼中,當文本更改時,將調用titleEditingChanged
(如預期的那樣)。 但是當它執行該行時
investment?.title = sender.text!
它稱Investment
為didset{}
。 為什么?
class InvestmentCell: UITableViewCell {
var investment: Investment? {
didSet {
// setup UI elements from class properties
textField.text = investment?.title
valueField.text = investment?.value?.description
}
}
@IBAction func titleEditingChanged(sender: UITextField) {
investment?.title = sender.text!
}
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var valueField: UITextField!
}
當設置類型實例的底層屬性時,也會調用值類型 (例如結構)的屬性觀察者; 只是因為實例本身的值已更新 。 同樣不適用於參考類型 ; 只要引用本身沒有變異,就不會調用屬性觀察者(即,引用本身可以被認為是引用類型的值)。
從語言指南 - 屬性 -我們讀到的屬性觀察者 :
財產觀察員觀察並回應財產價值的變化 。 每次設置屬性值時都會調用屬性觀察者,即使新值與屬性的當前值相同
要驗證上述內容,請考慮以下示例:
/* reference type */
class InvestmentC {
var title: String = "Foo"
}
/* value type */
struct InvestmentS {
var title: String = "bar"
}
class InvestmentContainer {
var investmentC : InvestmentC {
didSet {
print("did set a property of 'InvestmentC' instance (ref. type)")
}
}
var investmentS : InvestmentS {
didSet {
print("did set a property of 'InvestmentS' instance (val. type)")
}
}
init() {
investmentC = InvestmentC()
investmentS = InvestmentS()
}
}
/* Example: property observer called only when setting a property
of the value type instance 'investmentC' */
let foo = InvestmentContainer()
foo.investmentC.title = "foobar" // prints: nothing
foo.investmentS.title = "foobar" // prints: "did set a property of 'InvestmentS' instance (val. type)"
因此,我們可以推斷出您的自定義類型Investment
是一種值類型(結構),並且即使您只設置/更新此基礎屬性,也將調用此類型實例investment
的didSet
屬性觀察者(在您的UITableViewCell
子類中) investment
。 如果您想避免這種情況, didSet
Investment
更改為引用類型(類),在這種情況下,只有在設置/更新investment
實例本身時才會更改didSet
屬性觀察者。
這是因為Investment
可能是一個結構,而不是一個類。 在Swift中,結構是值類型,而不是類的引用類型。 因此,結構不是“可變的”。
這意味着每當您更改struct屬性時,都會分配一個新的struct對象來替換當前的對象,當前的對象數據將被復制到新的對象數據,但更改的屬性將包含新的值集。
請記住,每當使用let
命令初始化struct對象時,編譯器都不允許您更改struct屬性(使用類可以執行此操作)。
這就解釋了為什么每次更改struct屬性時都會調用觀察者。 一旦分配了新的struct對象來替換當前的對象,它現在將被存儲在另一個內存塊中,因此它的值將被更改並且將調用didSet
觀察者。
PS:如果將Investment
定義為類而不是結構,則不會發生這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.