简体   繁体   中英

How to observe a change in a class's property from another class

I've got a question on property observers. There's some example code below. What I want is for the property Analysis.hasChanged to be updated to true if a.value is changed. Is there a way I can do this?

class Number {
 var value: Double
 init(numberValue: Double) {
  self.value = NumberValue
 }
}

class Analysis {
 var a: Number
 var hasChanged = false
 init(inputNumber: Number) {
  self.a = inputNumber
 }
}

testNumber = Number(numberValue: 4)
testAnalysis = Analysis(inputNumber: testNumber)
print(testAnalysis.hasChanged) // will print "false"
testNumber.value = 10
print(testAnalysis.hasChanged) // will still print "false", but I want it to print "true"

In the end, I want the user to be able to be notified if any of their analyses use numbers that have been changed so that they can update the results of the analyses if they choose.

You can use the built-in property observers provided by Swift. Every time you set a new value, the didSet will be called. You just need to attach the closure, wrapping the desired behaviour, to the Number class

class Number {

    var valueDidChangeClosure: (()->())?
    var value: Double {
        didSet {

            //won't call the valueDidChangeClosure 
            //if the value was changed from 10 to 10 for example.. 

            if oldValue != value {
                valueDidChangeClosure?()
            }  
        }
    }
    init(numberValue: Double) {
        self.value = numberValue
    }
}

class Analysis {
    var a: Number
    var hasChanged = false
    init(inputNumber: Number) {
        self.a = inputNumber
        self.a.valueDidChangeClosure = {
            self.hasChanged = true
        }
    }
}

let testNumber = Number(numberValue: 4)
let testAnalysis = Analysis(inputNumber: testNumber)

print(testAnalysis.hasChanged) // will print "false"
testNumber.value = 10
print(testAnalysis.hasChanged) // will print "true"

I would do something like this, I apologize in advance if I have some syntax wrong (I usually use C/C++, think of this as more psudo code since you'd have to have a way to copy Number classes, etc.).

class Number {
 var value: Double
 init(numberValue: Double) {
  self.value = NumberValue
 }
}

class Analysis {
 var a: Number
 var _a: Number
 bool hasChanged() {
   if (a != _a) {
      _a = a
      return true;
   }
   return false;
 }
 init(inputNumber: Number) {
  self.a = inputNumber
  self._a = self.a
 }
}

testNumber = Number(numberValue: 4)
testAnalysis = Analysis(inputNumber: testNumber)
print(testAnalysis.hasChanged()) // will print "false"
testNumber.value = 10
print(testAnalysis.hasChanged()) // will still print "false", but I want it to print "true"

In the end, I want the user to be able to be notified if any of their analyses use numbers that have been changed so that they can update the results of the analyses if they choose.

I don't know if this really addresses that question, I based my answer off of the code you provided. So there may be additional functionality if you want there to be some triggering method (instead of calling .hasChanged()).

Comparing doubles (and any other floating point type) with '=' or '!=' is not a good idea.

Use epsilon function instead. Details: jessesquires.com/blog/floating-point-swift-ulp-and-epsilon/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM