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.
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