【问题标题】:Property Mysteriously Set To Nil属性神秘地设置为零
【发布时间】:2014-07-28 19:23:25
【问题描述】:

我正在尝试在我的应用程序中实现聊天功能,使用 Realm.io 作为内部数据库来存储聊天消息,并使用 PubNub 来发送和接收消息。我有 ChatSessions,它定义了发送消息的渠道,还有 ChatMessages,它代表消息本身,并保存对消息文本、消息发送日期、消息发件人姓名的引用,以及消息所属的 ChatSession。

在下面的代码中,我从通过通道接收到的 PNMessage 初始化 ChatMessage,并指定了所有字段。我遇到的问题是,当 Realm 将消息写入数据库时​​,ChatMessage 的会话字段设置为 nil,尽管事实上在调用 write 方法之前,会话字段具有指定的有效 ChatSession。

- (void)createChatMessageFromMessage:(PNMessage *)message
{
    NSDictionary *msgDict = message.message;
    ChatMessage *chatMessage = [[ChatMessage alloc] init];
    chatMessage.text = [msgDict objectForKey:@"text"];
    chatMessage.dateSent = [NSDate dateWithTimeIntervalSinceReferenceDate:[[msgDict objectForKey:@"dateSent"] floatValue]];
    chatMessage.sender = [msgDict objectForKey:@"sender"];
    NSPredicate *sessionPredicate = [NSPredicate predicateWithFormat:@"sessionName = %@", [msgDict objectForKey:@"session"]];
    RLMArray *matches = [ChatSession objectsWithPredicate:sessionPredicate];
    if ([matches count] == 1) {
        chatMessage.session = [matches firstObject];
        NSLog(@"Added chatMessage with session name: %@", chatMessage.session.sessionName);
    } else {
        NSLog(@"Error: ChatSession with name %@ not found in db.", [msgDict objectForKey:@"session"]);
        return;
    }
    [NSThread detachNewThreadSelector:@selector(writeToDefaultRealm:) toTarget:self  withObject:chatMessage];
}

#pragma mark - Saving to Realm

- (void)writeToDefaultRealm:(RLMObject *)object
{
    RLMRealm *defaultRealm = [RLMRealm defaultRealm];
    [defaultRealm beginWriteTransaction];
    [defaultRealm addObject:object];
    if ([object isKindOfClass:[ChatMessage class]]) {
        [((ChatMessage *)object).session.messages addObject:object];
        NSLog(@"Wrtiting message with text: %@ with session name: %@", ((ChatMessage *)object).text, ((ChatMessage *)object).session.sessionName);
    } else {
        NSLog(@"Writing session with name: %@", ((ChatSession *)object).sessionName);
    }
    [defaultRealm commitWriteTransaction];
}

设置 chatMessage.session 后的 NSLog 正确记录了我想要的内容。 chatMessage 具有正确的会话名称。但是,writeToDefaultRealm: 中的 NSLog 正确记录了消息文本,但记录了 session.sessionName 的 nil 值。

有人知道为什么这个会话字段被设置为 nil 吗?谢谢

编辑

ChatMessage.h

#import <Realm/Realm.h>

@class ChatSession;

@interface ChatMessage : RLMObject
// Add properties here to define the model
@property NSString *text;
@property NSDate *dateSent;
@property NSString *sender;
@property ChatSession *session;

@end

// This protocol enables typed collections. i.e.:
// RLMArray<ChatMessage>
RLM_ARRAY_TYPE(ChatMessage)

ChatSession.h

#import "ChatMessage.h"
#import <Realm/Realm.h>

@interface ChatSession : RLMObject

// Add properties here to define the model
@property NSDate *dateOpened;
@property NSDate *dateUpdated;
@property NSString *sessionName;
@property NSString *myAlias;
@property NSString *theirAlias;
@property RLMArray<ChatMessage> *messages;

@end

// This protocol enables typed collections. i.e.:
// RLMArray<ChatSession>
RLM_ARRAY_TYPE(ChatSession)

【问题讨论】:

  • 您介意发布ChatSessionChatMessage 的标题吗?
  • 当然可以。刚刚编辑。

标签: objective-c ios7 pubnub realm


【解决方案1】:

Realm 目前不支持在写入事务之外分配给 RLMObject 属性。所以当你做chatMessage.session = [matches firstObject];时,因为session是一个RLMObject属性(ChatSession),这必须在一个写事务中完成。这是一个可能的解决方案:

- (void)createChatMessageFromMessage:(PNMessage *)message
{
    NSDictionary *msgDict = message.message;
    ChatMessage *chatMessage = [[ChatMessage alloc] init];
    chatMessage.text = [msgDict objectForKey:@"text"];
    chatMessage.dateSent = [NSDate dateWithTimeIntervalSinceReferenceDate:[[msgDict objectForKey:@"dateSent"] floatValue]];
    chatMessage.sender = [msgDict objectForKey:@"sender"];
    NSPredicate *sessionPredicate = [NSPredicate predicateWithFormat:@"sessionName = %@", [msgDict objectForKey:@"session"]];
    RLMArray *matches = [ChatSession objectsWithPredicate:sessionPredicate];
    if ([matches count] == 1) {
        RLMRealm *defaultRealm = [RLMRealm defaultRealm];
        [defaultRealm beginWriteTransaction];
        chatMessage.session = [matches firstObject];
        [chatMessage.session.messages addObject:chatMessage];
        [defaultRealm addObject:chatMessage];
        [defaultRealm commitWriteTransaction];
        NSLog(@"Added chatMessage with session name: %@", chatMessage.session.sessionName);
    } else {
        NSLog(@"Error: ChatSession with name %@ not found in db.", [msgDict objectForKey:@"session"]);
        return;
    }
}

【讨论】:

  • 非常感谢!现在一切都很好
猜你喜欢
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
相关资源
最近更新 更多