gpt4 book ai didi

ios - 尝试使用 Grand Central Dispatch 执行 Realm 事务时出现 RLMException

转载 作者:行者123 更新时间:2023-11-28 05:30:47 25 4
gpt4 key购买 nike

我在我的 AppDelegate 中将这两个声明为全局变量

var realmdb: RLMRealm!
var realmQueue = dispatch_queue_create("com.pesto.realmdb", DISPATCH_QUEUE_SERIAL)

在我的 application(_, didFinishLaunchingWithOptions: _) 中,我将 defaultRealm 的引用设置为我的全局 realmdb,如下所示:

 dispatch_async(realmQueue) {
realmdb = RLMRealm.defaultRealm()
}

在我代码的另一个类中我有这个方法:

private func handleChatMessage(message: PSTChatMsg) {

// check if there is a channel environment for this message
PSTChatHelpers.getChannelEnvironmentForChannelName(message.channel) { channelEnvironments in

if channelEnvironments.count == 0 {

log.verbose("Channel environment for \(message.channel) does not exists. Creating...")

let newChannelEnvironment = PSTChatHelpers.createChannelEnvironmentFromMessage(message)
PSTChatHelpers.persistChannelEnvironmentChanges(newChannelEnvironment)

} else {

log.verbose("Pushing message to channel environment")

}

}
}

调用方法是这样实现的:

 class func getChannelEnvironmentForChannelName(channelName: String, withCompletionHandler handler: (results: RLMResults) -> ()) {

dispatch_async(realmQueue) {

let predicate = NSPredicate(format: "channelName = %@", channelName)
var channelEnv = PSTChannelEnvironment.objectsInRealm(realmdb, withPredicate: predicate)

handler(results: channelEnv)
}

}

/**
Creates a new PSTChannelEnvironment object wth values derived from passed PSTChatMsg

:param: message a PSTChatMsg to derive channel environment values from
:returns: The newly created PSTChannelEnvironment object
*/
class func createChannelEnvironmentFromMessage(message: PSTChatMsg) -> PSTChannelEnvironment {

let channelEnvironment = PSTChannelEnvironment()

channelEnvironment.channelName = message.channel
channelEnvironment.associatedPlaceId = message.associatedPlaceId
channelEnvironment.chattingWithUuid = ""
channelEnvironment.chattingWithUsername = ""
channelEnvironment.hasSessionEnded = false
channelEnvironment.unreadMessages = 0

return channelEnvironment

}

/**
Commits the passed PSTChannelEnvironment in Realm database

:param: The PSTChannelEnvironment to commit to Realm
*/
class func persistChannelEnvironmentChanges(channelEnvironment: PSTChannelEnvironment) {

dispatch_async(realmQueue) {

realmdb.beginWriteTransaction()
realmdb.addObject(channelEnvironment)
realmdb.commitWriteTransaction()

}
}

我从 getChannelEnvironmentForChannelName() 方法中得到 RLMException,原因:“从不正确的线程访问 Realm ”

我对如何使用 GCD 来处理我所有的 Realm 操作感到有点沮丧,因此非常感谢任何帮助!

最佳答案

由于通常线程和队列之间没有固定的关联(没有主队列,主队列只在主线程上运行,反之亦然),你不能只检索一个 RLMRealm 实例通过调度到您的队列并缓存它。 GCD 不保证同一个队列将再次由同一个线程执行。

我建议通过非缓存工厂方法来引用您的 Realm :

var realmdb : RLMRealm {
return RLMRealm.defaultRealm()
}

不用担心,在 RLMRealm 上定义的工厂方法本身已经实现了一个缓存策略,因此这个操作不会太昂贵,您仍然可以在每次使用时将实例缓存在本地 var 中。

如果你想传递它来解耦类之间的关系,你仍然可以将它写成一个函数类型:

var realmdb : () -> RLMRealm {
return { RLMRealm.defaultRealm() }
}

关于ios - 尝试使用 Grand Central Dispatch 执行 Realm 事务时出现 RLMException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28646323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com