我有如下设置:
// Queues
private static let mainQueue = dispatch_get_main_queue()
private static let writeQueue = dispatch_queue_create("com.tablelist.Tablelist.queue.realm.write", DISPATCH_QUEUE_SERIAL)
// Realms
private static let defaultRealm: Realm = try! Realm()
private static func getDefaultRealm(block: (Realm) -> ()) {
Dispatch.async(mainQueue) {
block(defaultRealm)
}
}
private static func getWriteRealm(block: (Realm) -> ()) {
Dispatch.async(writeQueue) {
block(try! Realm())
}
}
Run Code Online (Sandbox Code Playgroud)
最初我有一个,writeRealm但由于GCD不保证队列中的哪个线程运行,我被迫Realm在write func中每次创建一个新的.
然后我有一个公共功能:
/**
Asynchronously write data to the realm
*/
public static func write(block: (Realm) -> ()) -> Promise<Realm> {
let promise = Promise<Realm>()
getWriteRealm { writeRealm in
do {
try writeRealm.write {
block(writeRealm)
}
getDefaultRealm { realm in
promise.resolve(realm)
}
}
catch {
Dispatch.main {
promise.resolve(error)
}
}
}
return promise
}
Run Code Online (Sandbox Code Playgroud)
这允许调用者传入一个可以进行任何导入的块,然后在promise解析时获取主线程上的任何导入.问题是,有时导入的数据可用于Realm主线程,有时则不可用.这里有更好的方法吗?
编辑:只是为了澄清,如果我write在两种情况下更改func以获取默认域,我的所有测试都会通过.
解:
private static func getDefaultRealm(block: (Realm) -> ()) {
Dispatch.async(mainQueue) {
defaultRealm.refresh() // refresh the realm to bring to most recent state
block(defaultRealm)
}
}
private static func getWriteRealm(block: (Realm) -> ()) {
Dispatch.async(writeQueue) {
let realm = try! Realm()
realm.refresh() // refresh the realm to bring to most recent state
block(realm)
}
}
Run Code Online (Sandbox Code Playgroud)
解决方案2 :(进一步简化后)
private static func getDefaultRealm(block: (Realm) -> ()) {
let queue = dispatch_get_main_queue()
getRealm(queue, block: block)
}
private static func getWriteRealm(block: (Realm) -> ()) {
let queue = dispatch_queue_create("com.tablelist.Tablelist.queue.realm.write", nil)
getRealm(queue, block: block)
}
private static func getRealm(queue: dispatch_queue_t, block: (Realm) -> ()) {
Dispatch.async(queue) {
let realm = try! Realm()
realm.refresh()
block(realm)
}
}
Run Code Online (Sandbox Code Playgroud)
TL;博士; 要求Realm.refresh()将交易推进到最新状态.
Realm的事务是隔离的,以提供自我一致性.这允许在任何时间在任何线程上执行事务,而无需您明确锁定或使用其他类型的资源协调.
Realm中的读取和写入事务都基于最初初始化时最近成功的写入提交,并保留在该版本上直到刷新.除非将Realm的autorefresh属性设置为,否则领域会在每次runloop迭代开始时自动刷新false.如果一个线程没有runloop(通常是后台线程中的情况),那么Realm.refresh()必须手动调用才能将事务推进到最近的状态.
提交写入事务时,域也会刷新(Realm.commitWrite()).
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |