swiftdynamicrealmgetter-setter

WillSet/DidSet not being invoked on realm property


I have a problem because willSet and didSet are not being called with dynamic realm object.

Code sample:

try! realm.write {
    sut = Backup()
    realm.add(sut) // here willSet and didSet are invoked with nil object
}

XCTAssertFalse(sut.didEditPatient) // ok
try! realm.write {
    print("CHECKING: will add the patient")
    let patient = Patient()
    realm.add(patient)
    sut.patient = patient // nothing gets printed here!
    print("CHECKING: added the patient")
}

XCTAssertTrue(sut.didEditPatient) // fails
XCTAssertNotNil(sut.patient) // ok

Where Backup class is defined this way:

final class Backup: Object {
    @objc dynamic var patient: Patient? {
        willSet {
            print("CHECKING: willSet: \(String(describing: newValue))")
            if newValue != patient {
                didEditPatient = true
            }
        }
        didSet { print("CHECKING: didSet: \(String(describing: patient))") }
    }
    @objc dynamic var didEditPatient: Bool = false

Output in the console is:

While I'd rather expect that between will add the patient and added the patient I should get willSet and didSet with patient object. Obviously, patient is not nil.


Solution

  • There is one issue described about this in realm repo:


    I would recommend using a private persisted property which has no logic, along with a non-persisted computed property which has the willSet/didSet functionality:

    class Model : RLMObject {
        private dynamic var backingProp = 0
    
        var prop : Int {
            get {
                return backingProp
            }
            set(newValue) {
                // do willSet stuff
                backingProp = newValue
                // do didSet stuff
            }
        }
    
        override class func ignoredProperties() -> [AnyObject]! {
            return ["prop"]
        }
    }
    

    This is a bit verbose, but gives you identical behavior for objects in a realm and standalone objects.


    Source: https://github.com/realm/realm-cocoa/issues/870#issuecomment-54543539