所以我正在设置一个后台队列,它在自己的线程上执行所有域写操作。我遇到了一些我无法弄清楚的奇怪问题。
我不确定这是否相关(请参阅帖子:Xcode debug issues with realm)但我的lldbg
输出明显与某个字段是否存在不匹配:
messages
元素
class OTTOSession : Object {
dynamic var messages : MessageList?
dynamic var recordingStart : Double = NSDate().timeIntervalSince1970
func addLocationMessage(msg : dmParsedMessage) -> LocationMessage {
let dmsg : dmLocationMessage = msg as! dmLocationMessage
let locMsg = LocationMessage(locMsg: dmsg)
self.messages!.locationMessages.append(locMsg)
return locMsg;
}
}
public class MessageList : Object {
dynamic var date : NSDate = NSDate();
dynamic var test : String = "HI";
let locationMessages = List<LocationMessage>()
let ahrsMessages = List<AHRSMessage>()
// let statusMessages = List<StatusMessageRLM>()
let logMessages = List<LogMessage>()
}
在我的代码中,我在OTTOSession
realmQueue
internal var realmQueue = dispatch_queue_create("DataRecorder.realmQueue",
DISPATCH_QUEUE_SERIAL)
所有领域调用都在此realmQueue
线程
dispatch_async(realmQueue) {
self.session = OTTOSession()
}
我也尝试了不同的变体,例如:
dispatch_async(realmQueue) {
self.session = OTTOSession()
// Directly making a message list
self.session!.messages = MessageList()
//Making a separate message list var
self.messages = MessageList()
self.session!.messages = self.messages
}
我使用MessageList
的原因是,我无法从调试器告知.messages
变量是否已设置
一旦我向我的进程发出信号,我想开始录制,然后实际将写入调用进入Realm(我不能100%确定我正确地做了)
dispatch_async(realmQueue){
// Update some of the data
self.session!.recordingStart = NSDate().timeIntervalSince1970
// Then start writing the objects
try! Realm().write {
// I've tried different variants of:
let session = self.session!
try! Realm().add(self.session!)
// Or
try! Realm().add(self.session!)
// or
let session = self.session!
session.messages = MessageList()
session.messages!.ahrsMessages
try! Realm().add(self.session!)
try! self.session!.messages = Realm().create(MessageList)
try! Realm().add(self.session!.messages!)
print ("Done")
}
}
基本上我已尝试过尝试将对象变为领域的各种组合。
问题:添加具有one-to-one
关系的对象时,我必须将两个对象添加到Realm,或者只添加parent
对象,导致相关对象也被添加到领域
当事情开始出错时,我开始向我的对象添加数据。
在我的OTTOSession
对象中,我有以下功能:
func addLocationMessage(msg : dmParsedMessage) -> LocationMessage {
let dmsg : dmLocationMessage = msg as! dmLocationMessage
let locMsg = LocationMessage(locMsg: dmsg)
// THIS LINE IS CAUSING A 'REALM ACCESSED FROM INCORRECT THREAD ERROR
self.messages!.locationMessages.append(locMsg)
return locMsg;
}
我在这一行收到了访问错误:
self.messages!.locationMessages.append(locMsg)
现在函数调用本身包含在以下块中:
dispatch_async(realmQueue) {
try! Realm().write {
self.session?.addLocationMessage(msg)
}
}
据我所知,通过查看调试器 - 并查看代码 - 一切都应该在正确的线程内运行。
我的队列是SERIAL
所以事情应该一个接一个地发生。我唯一能做的就是当我在这一点上突破时调试器确实显示messages
是nil
,但我不相信,因为:
所以我的问题是两次
1)我的代码是否正确地将对象添加到RealmDB中。即我是否需要为Realm().add
和OTTOSession
分别进行两次MessageList
来电,或者我可以通过一次通话取消
2)是否有任何东西可以解释为什么我在这里遇到线程违规 - 我应该在单个线程上编写所有内容吗?
答案 0 :(得分:2)
1)不,您不需要对Realm.add()
进行两次单独的调用。将对象添加到Realm时,所有相关对象也会保持不变。
2)您的线程违规很可能源于这样一个事实,即调度队列无法保证执行它们的线程(在主队列旁边)。这意味着您的Realm队列在不同的线程上执行。您需要确保从此线程上打开的Realm中检索会话对象。您可能希望为此目的使用主键并在队列/线程之间共享它们。