【问题标题】:Realm errors: RLMArray and Migration领域错误:RLMArray 和迁移
【发布时间】:2015-07-22 04:57:04
【问题描述】:

我在尝试编译我的领域代码时遇到了一些错误,这是代码的第一个版本:

import RealmSwift

class Test: Object {
    dynamic var name = ""
    dynamic var dict = Dictionary<String, Int>()
    dynamic var owner: TestList?
}


class TestList: Object{
    dynamic var name = ""
    let tests = List<Test>().filter("ALL Test.dict[hello] != nil")
}

//ViewController

import RealmSwift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let realm = Realm()
        let test1 = Test()
        test1.name = "test1"
        test1.dict = ["hello": 1]
        realm.write{realm.add(test1)}
        let test2 = Test()
        test2.name = "test2"
        test2.dict = ["nihao": 2]
        realm.write{realm.add(test2)}

        let test3 = Test()
        test3.name = "test3"
        test3.dict = ["hello": 3]
        realm.write{realm.add(test3)}
    }


    @IBOutlet weak var label: UILabel!

    @IBAction func set(sender: UIButton){
        let test = Test()
        let realm = Realm()
        test.name = "not using CoreData"
        realm.write{realm.add(test)}
        text = "abc"
    }        

    @IBAction func show(sender: UIButton){

        let test = Realm().objects(TestList)
        var str = ""
        println("got to here")
        for i in test{
            str += " \(i.name)"
        }
        label.text = str
    }
}

使用此设置后,我的日志中出现错误消息: Terminating app due to uncaught exception 'RLMException', reason: 'This method can only be called on RLMArray instances retrieved from an RLMRealm'

当我在我的 TestList 对象中删除过滤时,错误变为:Terminating app due to uncaught exception 'RLMException', reason: 'Migration is required for object type 'Test' due to the following errors: - Property 'dict' has been added to latest object model. - Property 'owner' has been added to latest object model.'

我对 Realm 文档的理解完全错误吗?

【问题讨论】:

    标签: ios swift realm


    【解决方案1】:

    第一个错误是正确的。您无法过滤属性。此外,Realm 目前不允许 Dictionary 属性。您需要将其显式建模为专用 Realm 对象实体的列表属性,该实体具有保存 String 和 Int 的字段。

    class Test: Object {
        dynamic var name = ""
        dynamic var dict = List<TestRelatedThing>()
        dynamic var owner: TestList?
    }
    
    class TestRelatedThing : Object {
       dynamic var key: String
       dynamic var value: Int
    }
    
    class TestList: Object{
        dynamic var name = ""
        let tests = List<Test>()
    }
    

    然后您可以通过以下方式在运行时查询:

    Realm().objects(TestList).filter("ANY tests.key == %@", "hello")
    

    提示:Realm 不支持聚合运算符ALL。请参阅我们的 predicate cheat sheet 以获取支持的运算符的完整列表。在这里,存在量化该操作更有意义,因为数据结构发生了变化,它不允许具有 value 属性的 TestRelatedThing 条目首先存在等于 nil。因此,您只需确保有一个带有键 "hello" 的条目即可。

    对于第二个错误:我猜您尝试在之前运行您的代码,然后在第一次运行您的模型对象之后添加更多字段。

    您可以重置模拟器状态,或者只需添加以下代码行之一,以确保在开发过程中每次运行时都以新的 Realm 开始。

    # Swift 1.2
    var error: NSError?
    NSFileManager.defaultManager().removeItemAtPath(Realm.defaultPath, error:&error)
    
    # Swift 2
    try! NSFileManager.defaultManager().removeItemAtPath(Realm.defaultPath)
    

    【讨论】:

    • 非常感谢您的详细解答!我能够修复几乎所有错误,但我不太了解最后一个错误的修复,似乎如果我不从新领域开始,每次调用时查询结果都会建立起来。因此,每次运行程序时,我最终都会得到一组结果。
    • 是的,没错。如果你没有从一个新的领域开始,你的查询结果会在每次运行后多包含一个结果,因为你在视图控制器的 viewDidLoad 方法中添加了对象。这些更改是持久的。毕竟这就是你使用 Realm 的目的,对吧? ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多