0

I am getting error as below

Invalid property name , reason: 'Property 'IsRecordDeleted' not found in object of type 'MyCustomModel'

Where as my Model is as Under

@objcMembers public class MyCustomModel : Object {
dynamic var   Id : String = ""
dynamic var   ProductId : String? = ""
dynamic var   IsRecordDeleted : Bool? = false
dynamic var   ProductBarcode : String? = ""


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

}

and I am making query like this :

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self).filter("IsRecordDeleted = false")

What could be problem here. I do not know why my app is crashing with the same error. But If I change the value like

    let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self).filter("ProductId = 0")

The app gets run, but crashed on when I use IsRecordDeleted in predicate.

Please tell me what could be problem

4

2 回答 2

3

You can try

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self)
let filtered = mSavedItems.filter { $0.IsRecordDeleted == false }

and

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self) 
let filtered = mSavedItems.filter { $0.ProductId == "0" }

For both

let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self) 
let filtered = mSavedItems.filter {
   $0.IsRecordDeleted == false 
   && $0.ProductId == "0" 
}

//

let resultPredicate = NSPredicate(format: "ProductId == '0' AND IsRecordDeleted == false")
let filtered = mSavedItems.filter(resultPredicate)
于 2018-09-05T14:11:46.917 回答
2

I think you'll find that simply switching to filter blocks instead of string predicates might stop the crash, but will not produce the expected results.

This is because IsRecordDeleted never gets saved to the database. It is not a type that can be represented in Objective-C, therefore it cannot be dynamic, so Realm ignores it.

Take as an example the following class:

@objcMembers class MyObject: Object {
    dynamic var id = ""
    dynamic var testBool: Bool? = false

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

And say we initialize them like this:

    let obj1 = MyObject()
    obj1.id = "1"
    obj1.testBool = true

    let obj2 = MyObject()
    obj2.id = "2"
    obj2.testBool = false

    let realm = try? Realm()
    try? realm?.write {
        realm?.add(obj1, update: true)
        realm?.add(obj2, update: true)
    }

If we query Realm for these objects using realm.objects(MyObject.self), you'll get something like this

Results<MyObject> <0x7fe410c0ad90> (
    [0] MyObject {
        id = 1;
    },
    [1] MyObject {
        id = 2;
    }
)

And you'll see that in the database, there indeed is no property named testBool, which was our optional Bool.

You can easily see that the optional Bool may cause problems if you write it out like this instead:

class MyObject: Object {
    @objc dynamic var id = ""
    @objc dynamic var testBool: Bool? = false   // This line will not compile.

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

I'm curious why the IsRecordDeleted needs to be optional in the first place, since it seems to have a value from the get-go. If it doesn't, then something like this will work as expected:

@objcMembers public class MyCustomModel: Object {
    dynamic var Id: String = ""
    dynamic var ProductId: String? = ""
    dynamic var IsRecordDeleted: Bool = false
    dynamic var ProductBarcode: String? = ""


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

and you can query via string like you were trying to do in the first place.

If it has to be optional, then Realm provides a RealmOptional for this exact case, that you can look into here.

于 2018-09-05T15:26:22.527 回答