领域模型包含属性,但在运行时找不到

时间:2018-09-05 14:07:51

标签: ios realm swift4 realm-database

我收到如下错误

  

无效的属性名称,原因:在“ MyCustomModel”类型的对象中找不到“ Property'IsRecordDeleted”

我的模型在哪里

@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"
}

}

我正在这样查询:

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

这里可能是问题。我不知道为什么我的应用程序因相同的错误而崩溃。但是如果我更改

之类的值
    let mSavedItems = mDbHelper.realmObj.objects(MyCustomModel.self).filter("ProductId = 0")

该应用程序开始运行,但是当我在谓词中使用IsRecordDeleted时崩溃。

请告诉我可能是什么问题

2 个答案:

答案 0 :(得分:2)

您可以尝试

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

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

两者都

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)

答案 1 :(得分:1)

我认为您会发现,仅切换到过滤器块而不是字符串谓词可能会停止崩溃,但不会产生预期的结果。

这是因为IsRecordDeleted从未保存到数据库。它不是可以在Objective-C中表示的类型,因此不能为dynamic,因此Realm会忽略它。

以以下类为例:

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

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

说我们像这样初始化它们:

    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)
    }

如果我们使用realm.objects(MyObject.self)向Realm查询这些对象,则会得到类似的信息

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

您会看到在数据库中,确实没有名为testBool的属性,这是我们可选的Bool

您可以很容易地看到,如果以这种方式写出可选的Bool可能会导致问题:

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"
    }
}

我很好奇为什么IsRecordDeleted首先需要是可选的,因为它似乎从一开始就具有价值。如果没有,那么这样的事情将按预期工作:

@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"
    }
}

,您可以像最初一样尝试通过字符串查询。

如果必须是可选的,那么Realm会为此确切情况提供一个RealmOptional,您可以查看here