【问题标题】:Duplicate objects in RLMArray one-To-Many RelationshipsRLMArray 一对多关系中的重复对象
【发布时间】:2015-12-05 22:55:14
【问题描述】:

我有一个没有我的领域数据库的问题。我有这些对象:

// Person.h
@interface Person : RLMObject
//... property declarations
@property RLMArray<Dog *><Dog> *dogs;
@end

// Dog.h
@interface Dog : RLMObject
@property NSInteger id;
@property NSString *name;
@end

RLM_ARRAY_TYPE(Dog) // Defines an RLMArray<Dog> type 

// Dog.m
@implementation Dog
+ (NSString *)primaryKey {
    return @"id";
}
@end

当我做这个时,我会在 Person.dogs 中得到 2 个相同的对象

Person *jim = [[Person alloc] init];
Dog *rex = [[Dog alloc] init];
rex.id = 1;
rex.name = @"Rex";

RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm addObject:jim];
[realm commitWriteTransaction];

[realm beginWriteTransaction];
[jim.dogs addObject:rex];
[realm commitWriteTransaction];

[realm beginWriteTransaction];
[jim.dogs addObject:rex];
[realm commitWriteTransaction];

在这之后我应该怎么做,我将只有一个具有唯一主键的对象?我知道 RLMArray 只是一个数组,但我认为该领域很早就意识到一对多关系只有唯一的对象。

这是来自 Realm 浏览器和 Xcode 调试区域的屏幕截图

这里有 3 条狗,因为我的代码运行了 3 次,但这没关系,我可以用我的 ID 制作狗,但在这种情况下没关系

【问题讨论】:

    标签: ios objective-c realm


    【解决方案1】:

    RLMArray 具有数组语义。它不像一个集合,它只包含唯一的对象。这意味着您可以多次添加同一个对象。如果你想最后每种类型只有一个对象,你应该只添加一个对象。

    您发布的调试器的输出表明您运行了您的应用程序 3 次,但狗每次都有不同的 id,因此它们被威胁为不同的对象。

    如果您要使用[Person createOrUpdateInRealm:realm withValue:jim];,其中jimNSDictionary 或只有一条狗且狗的id 和人的id 等于您的领域中持久存在的id 的独立对象,那么您将最终仍然只有一个人和一只狗,并且它们所有剩余的属性都将具有更新的值。

    【讨论】:

    • @maruis dog id 在这种情况下无效。因为我可以用相同的 ID 拯救一只狗 2 次。我在上面添加了一个屏幕截图。
    • 现在我的狗桌上有一只狗,但狗关系中有 2 只或更多狗。
    • 你最终在关系中多次拥有狗,因为你多次添加它们。如果您不想多次添加它们,那么您需要检查它是否已添加,并且仅在尚未添加时才添加。
    • 我同意@marius,我已将其添加到我的答案中。
    • @marius 我明白,但我不想自己检查,Core Data+magical record 可以自动完成。因为我需要检查对象中的所有属性,然后如果我有差异,我应该替换它。
    【解决方案2】:

    我想是因为你还没有坚持任何东西。

    如果您使用相同的主键持久化 RLMObjects,领域将抛出异常(因为主键)。

    // Update or create jim with with the dogs
    [realm beginWriteTransaction];
    [Person createOrUpdateInRealm:realm withValue:jim];
    [realm commitWriteTransaction];
    
    // Or add Jim with the dogs to Realm with transaction
    [realm beginWriteTransaction];
    [realm addObject:jim];
    [realm commitWriteTransaction];
    

    编辑:我同意 Marius 的观点,如果您首先单独保留狗,然后将其添加到 Person(一对多)中,您不会不再有问题了,因为当单独持久化狗时,领域会首先抛出异常。

    【讨论】:

    • 不,这不起作用。我忘了在我的问题中添加这行代码
    • @NosovPavel 你确定这些狗是坚持的吗?你在 Realm 浏览器中验证了吗?
    • 是的,现在您可以在我的问题末尾看到屏幕截图。
    • @NosovPavel 我使用了不同的 ID 类型,不是 NSInteger,而是原始类型“long”。也许那里出了问题..
    • 这行不通。因为在文档中写了 NSInteger。
    猜你喜欢
    • 2012-04-18
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    相关资源
    最近更新 更多