Why is 'didset' called on a property when I set the property of that property?

后端 未结 2 490
感动是毒
感动是毒 2021-01-11 18:03

In this code when the text changes, titleEditingChanged is called (as expected). But when it executes the line

investment?.title = sender.text!         


        
2条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-11 18:05

    Property observers of value types (e.g. structures) are called also when an underlying property of the type instance is set; simply since the value of the instance itself is updated. The same does not hold for reference types; as long as the reference itself is not mutated, the property observer will not be called (i.e., the reference itself can be considered the value of reference types).

    From Language Guide - Properties - Property Observers we read:

    Property observers observe and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value


    To verify the above, consider the following example:

    /* 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)"
    

    Hence, we can infer that your custom type Investment is a value type (a structure), and the didSet property observer of the instance investment of this type (in your UITableViewCell subclass) will be called even if you only set/update underlying properties of investment. If you'd like to avoid this, change Investment into a reference type (class), in which case the didSet property observer will only be changed if the investment instance itself is set/updated.

提交回复
热议问题