Realm-cocoa: Persisted objects from Realm are returned with unset properties

Created on 10 Dec 2017  路  7Comments  路  Source: realm/realm-cocoa

Objects retrieved from a Realm using realm.object(ofType:, forPrimaryKey:) or realm.objects(type:) do not have their properties set to stored ones, instead the object has default values.

Code Sample

The model that's being persisted:

@objcMembers
class DMEventPeer: Object {

    dynamic var id: Int = 0
    dynamic var fullName: String? = nil
    dynamic var isHost: Bool = false
    dynamic var isConnected: Bool = false
    dynamic var isSelf: Bool = false

    override class func primaryKey() -> String? {
        return "id"
    }
}

Persisting code:

let peer = DMEventPeer()
peer.isSelf = true
peer.isHost = true
let realm = try! Realm()
try! realm.write {
    peer.id = (realm.objects(DMEventPeer.self).max(ofProperty: "id") ?? 0) + 1
    realm.add(peer)
}

Querying code:

let realm = try Realm()
let selfPeer = realm.objects(DMEventPeer.self).filter("isSelf == true").first

let selfPeer values in debug view is as follows:
screen shot 2017-12-10 at 11 56 41

Interestingly, if I declare a variable in lldb or just do po realm.objects(DMEventPeer.self).filter("isSelf == true").first the values are correct:

screen shot 2017-12-10 at 11 58 33

Obviously I'm missing something basic here, but this is really strange nonetheless.

Version of Realm and Tooling

Realm framework version: 3.0.2

Realm Object Server version: none used

Xcode version: 9.2

iOS/OSX version: 11.2

Dependency manager + version: CocoaPods 1.3.1

Most helpful comment

The instance variables of a Realm Object subclass are only used for objects that have not yet been added to a Realm. After an object has been added to a Realm, or for an object that was retrieved from a Realm, the objects getters and setters access data directly from the Realm without the use of the instance variables. This is why the instance variables in Xcode's debugger view do not have the values you expect.

Do you see the correct values if you access the properties directly? Do you see the correct values if you print the object's description?

All 7 comments

Are you using Swift 3.* or Swift 4? If the latter, you need to mark your properties as @objc dynamic, not just dynamic, because Swift 4 no longer infers @objc from dynamic.

I'm using Swift 4. Actually, the model class is marked as @objcMembers, I just failed to copy it here.

edit:

tried to replace @objcMembers to @objc for properties, still no luck

@austinzheng here's a example project that reproduces this issue https://github.com/MindaugasJucius/RealmUnsetPropertiesExample/

The instance variables of a Realm Object subclass are only used for objects that have not yet been added to a Realm. After an object has been added to a Realm, or for an object that was retrieved from a Realm, the objects getters and setters access data directly from the Realm without the use of the instance variables. This is why the instance variables in Xcode's debugger view do not have the values you expect.

Do you see the correct values if you access the properties directly? Do you see the correct values if you print the object's description?

@bdash thanks for your response.
As you said, accessing a property directly returns the desired values.

An unrelated question, is there a way (besides realm notifications) to be aware when an instance property sets its value?

My model has a computed property that depends on a Data type property stored in Realm. I would like set my computed property to unarchived value of the stored property

You should be able to just use didSet or willSet for that purpose.

That doesn't seem to work. I found this https://github.com/realm/realm-cocoa/issues/870, maybe that'll be of some help.

Anyway, I'm closing this issue. Thanks for your help!

Was this page helpful?
0 / 5 - 0 ratings