【问题标题】:Adding a RLMObject to another objects RLMArray only works first time将 RLMObject 添加到另一个对象 RLMArray 仅在第一次有效
【发布时间】:2016-06-22 20:22:57
【问题描述】:

对于我的应用程序的聊天部分,我试图将对话数据保存到设备中,这样用户就不需要在每次打开应用程序时都刷新。

从数据库中获取所有消息后,我循环遍历数组并将它们存储在会话模型消息属性 (RLMArray) 中。

由于每条消息都有一个主键,因此在将其添加到对话消息之前,我还会检查领域以查看该消息是否已经存在。这在我第一次使用该应用程序时工作正常,但如果我再次运行它,我会收到此错误:

'RLMException', reason: 'Can't set primary key property 'serverID' to existing value '1355'.'

这是我将消息添加到领域的代码

RLMRealm *realm = [RLMRealm defaultRealm];
        [realm beginWriteTransaction];
        for (Message *model in messageArray) {
            NSLog(@"message model: %@", model);
            TERMessage *message = [[TERMessage alloc] initWithMessage:model];
            TERMessage *existingObject = [self.model.messages objectsWhere:@"serverID == %@",message.serverID].firstObject;
            NSLog(@"existing object: %@", existingObject);
            if (existingObject == nil) {
                [self.model.messages addObject:message];
            } else {
                NSLog(@"not being aded");
            }
        }
        [realm commitWriteTransaction];

【问题讨论】:

    标签: objective-c realm


    【解决方案1】:

    查看您的代码,您正在查询具有相同serverIDTERMessage 对象是否已经属于self.model。话虽这么说,虽然另一个TERMessage 对象可能尚未链接到self.model,但很可能该对象仍然存在于领域中(即它位于领域文件中的TERMessage 表中) .

    如果是这种情况,那么当您创建第二个 TERMessage 对象并尝试将其添加到 self.model 时,Realm 会尝试将其添加到 TERMessage 表并发现具有相同主对象的另一个对象密钥已存在。

    要解决此问题,您需要使查询逻辑更加彻底,以确保它在发生这种情况时正确捕获原始对象。

    首先,您可以使用[RLMObject objectForPrimaryKey:] 来查看具有主键的对象是否已经存在。如果是,那么你可以使用 Realm 的逆向关系特性来查看它是否已经属于self.model

    @interface TERMessage : RLMObject
    //... other properties
    @property (readonly) RLMLinkingObjects *models;
    @end
    
    // --
    
    @implementation TERMessage
    + (NSDictionary *)linkingObjectsProperties {
        return @{
            @"models": [RLMPropertyDescriptor descriptorWithClass:Message.class propertyName:@"model"],
        };
    }
    @end
    
    // --
    
    RLMRealm *realm = [RLMRealm defaultRealm];
    [realm beginWriteTransaction];
    for (Message *model in messageArray) {
        NSLog(@"message model: %@", model);
    
        // Check to see if an entry exists and it is a linked object of our model object
        TERMEssage *previousMessage = [TERMessage objectForPrimaryKey:message.serverID];
        if (previousMessage != nil && [previousMessage.models indexOfObject:self.model] != NSNotFound) {
            continue;
        }
    
        // If the object exists, but it's not assigned to the model, assign it
        if ([previousMessage.models indexOfObject:self.model] == NSNotFound) {
            [self.model.messages addObject:previousMessage];
            continue;
        }
    
        //Create and add a new message object
        TERMessage *message = [[TERMessage alloc] initWithMessage:model];
        [self.model.messages addObject:message];
    }
    [realm commitWriteTransaction];
    

    【讨论】:

    • 这行得通!这些属性在我的项目中具有不同的名称,但该过程有效!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    相关资源
    最近更新 更多