Realm-cocoa: Swift didSet and willSet on properties in a RLMObject

Created on 4 Sep 2014  路  4Comments  路  Source: realm/realm-cocoa

I just started trying out Realm.io and looks really good so far.

I ran across this weird thing with Swifts didSet and willSet on properties.
I have a Recipe class with this property:

dynamic var is_server_send : NSInteger = IS_SERVER_SEND.NO.toRaw() { didSet { self.synchronize() } }

I instantiate the object:

var rec = Recipe(recipeId: 10, genreId: 12, subGenreId: 13)
rec.name = "A name"
rec.is_server_send = IS_SERVER_SEND.YES.toRaw()

And the synchronize() method is invoked.
Then I add it to the realm:

        realm.beginWriteTransaction()
        realm.addObject(rec)
        realm.commitWriteTransaction()

Later I want to make some changes and set the property again:

realm.beginWriteTransaction()
rec.is_server_send = IS_SERVER_SEND.NO.toRaw()
realm.commitWriteTransaction()

But now the synchronize() method is not called.
If I implement the willSet on the property then that is called on the second change, so I can just implement that as well.

dynamic var is_server_send : NSInteger = IS_SERVER_SEND.NO.toRaw() { didSet { self.synchronize() } willSet { self.synchronize()} }

So it's not anything that can't be dealt with, just wondering what the reason for it might be?

I'm on Xcode beta 6.

Most helpful comment

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.

All 4 comments

willSet and didSet only works on an RLMObject before it is added to a realm.

This is necessary to maintain one of Realm's powerful features: setting/getting properties interacts with the underlying database values directly.

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.

This does not seem to be possible at the moment in swift.

This should be documented. I just spent 2 hours trying to figure this out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ishidakei picture ishidakei  路  3Comments

i-schuetz picture i-schuetz  路  3Comments

fadylateef picture fadylateef  路  3Comments

carvalho-oak picture carvalho-oak  路  3Comments

matteodanelli picture matteodanelli  路  3Comments