在Realm中复制对象时的奇怪行为

时间:2017-05-03 14:22:48

标签: ios swift realm

以下代码通过从名为ItemList的现有Second List复制Item来创建名为ItemList的新First List。创建Second List后,我想删除Item中的所有First List,我的问题是由于某些原因我调用deleteItemsFromFirstList()方法删除第一项中的项目列表中Item的最后一个Second List已被删除并移至Fist List,因此,我最后在Item中使用了一个{1} First List并且最后ItemSecond List中缺少1}}。理论上Second List应该包含所有三(3)个项目,First List应为空。我希望这是有道理的。

我做错了什么?

编辑: 我希望能够做的是将项目从第一个列表复制到第二个列表,然后从第一个列表中删除项目,但在Realm中保留First List(空)。

以下是代码:

领域对象模型

class Item:Object{
    dynamic var basePrice:Double = 0
    dynamic var productName:String = ""
    dynamic var createdAt = NSDate()
}

class ItemList: Object {
    dynamic var listName = ""
    dynamic var createdAt = NSDate()
    let items = List<Item>()
}

添加和删除方法

func newList()     
    let newList = ItemList()
    newList.listName = "Second List"

    if let firstList = realm.objects(ItemList.self).filter("listName = %@", "First List").first{
        let itemsFromFirstList = firstList.items

        try! realm.write {
            for i in itemsFromFirstList{
                let obj = realm.create(Item.self)
                obj.basePrice = i.basePrice
                obj.productName = i.productName
                newList.items.append(obj)
                realm.add(newList)
            }
        }
    }
}

func deleteItemsFromFirstList(){
    let listToDelete = realm.objects(ItemList.self).filter("listName = %@", "First List").first

    try! realm.write {
        for i in (listToDelete?.items)! {
            realm.delete(realm.objects(Item.self).filter("productName = %@", i.productName).first!)
        }
    }
}

输出

现有列表:这就是First List的样子(代码未显示创建)

Results<ItemList> (
    [0] ItemList {
        listName = First List;
        createdAt = 2017-05-03 01:32:45 +0000;
        items = RLMArray <0x6100000f4100> (
            [0] Item {
                basePrice = 1;
                productName = Apples;
                createdAt = 2017-05-03 01:32:57 +0000;
            },
            [1] Item {
                basePrice = 2;
                productName = Oranges;
                createdAt = 2017-05-03 01:33:04 +0000;
            },
            [2] Item {
                basePrice = 3;
                productName = Bananas;
                createdAt = 2017-05-03 01:33:13 +0000;
            }
        );
    }
)

创建Second List后。在这一点上,两个列表看起来都是相同的,这就是我想要的。

Results<ItemList> (
    [0] ItemList {
        listName = First List;
        createdAt = 2017-05-03 01:32:45 +0000;
        items = RLMArray <0x6080000f5680> (
            [0] Item {
                basePrice = 1;
                productName = Apples;
                createdAt = 2017-05-03 01:32:57 +0000;
            },
            [1] Item {
                basePrice = 2;
                productName = Oranges;
                createdAt = 2017-05-03 01:33:04 +0000;
            },
            [2] Item {
                basePrice = 3;
                productName = Bananas;
                createdAt = 2017-05-03 01:33:13 +0000;
            }
        );
    },
    [1] ItemList {
        listName = Second List;
        createdAt = 2017-05-03 01:34:03 +0000;
        items = RLMArray <0x6080000f5b00> (
            [0] Item {
                basePrice = 1;
                productName = Apples;
                createdAt = 2017-05-03 01:34:03 +0000;
            },
            [1] Item {
                basePrice = 2;
                productName = Oranges;
                createdAt = 2017-05-03 01:34:03 +0000;
            },
            [2] Item {
                basePrice = 3;
                productName = Bananas;
                createdAt = 2017-05-03 01:34:03 +0000;
            }
        );
    }
)

调用deleteItemsFromFirstList()方法后。请注意,在此调用之前,这两个列表都有三(3)个Item s,但现在Second List只有两个,First List最后只有一个(1)。理论上Second List应该包含所有三(3)个项目,First List应为空。

Results<ItemList> (
    [0] ItemList {
        listName = First List;
        createdAt = 2017-05-03 01:32:45 +0000;
        items = RLMArray <0x6100000f1f00> (
            [0] Item {
                basePrice = 3;
                productName = Bananas;
                createdAt = 2017-05-03 01:33:13 +0000;
            }
        );
    },
    [1] ItemList {
        listName = Second List;
        createdAt = 2017-05-03 01:34:03 +0000;
        items = RLMArray <0x6100000f6400> (
            [0] Item {
                basePrice = 1;
                productName = Apples;
                createdAt = 2017-05-03 01:34:03 +0000;
            },
            [1] Item {
                basePrice = 2;
                productName = Oranges;
                createdAt = 2017-05-03 01:34:03 +0000;
            }
        );
    }
)

知道我做错了吗?

1 个答案:

答案 0 :(得分:1)

您不应该尝试删除这些项目,因为当您将它们添加到列表中时,实际上并不是在Realm中复制项目本身,只需将项目的引用添加到第二个列表中。

首先,您应该澄清您实际想要实现的目标。如果要删除第一个列表而不删除它的项目,请从Realm中删除ItemList对象,而不是ItemList.list元素的Item对象。

如果您确实要从Realm中删除对象,则不能只过滤其名称,因为两个列表中的名称相同,您必须过滤例如createdAt属性。如果选择此方法,则应在将列表添加到列表后将每个项目的createdAt属性更改为列表的相同属性,这样就可以通过它进行过滤。