Ho una configurazione simile al seguente:dati scritti uno sfondo Realm non è disponibile immediatamente per Realm principale
// 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())
}
}
Inizialmente ho avuto un writeRealm
ma poiché GCD non dà alcuna garanzia su quale filo di un blocco in una coda viene eseguito, sono stato costretto a creare un nuovo Realm
ogni volta nella funzione di scrittura.
Ho poi hanno un func pubblico:
/**
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
}
Questo consente al chiamante di passare in un blocco in cui può fare qualsiasi importazione, e poi prendere qualsiasi importazione sul thread principale quando la promessa si risolve. Il problema è che a volte i dati importati sono disponibili per lo Realm
sul thread principale e, a volte, non lo sono. C'è un approccio migliore qui?
MODIFICA: solo per chiarire, se cambio la funzione write
per accedere al dominio predefinito in entrambi i casi, passano tutti i miei test.
SOLUZIONE:
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)
}
}
SOLUZIONE 2: (After semplificando ulteriormente)
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)
}
}
Incredibile ha funzionato, grazie! Funzioni aggiornate pubblicate sopra, puoi confermare che ho bisogno di richiamare l'aggiornamento in entrambe le funzioni 'get'? – Andrew
Anche l'aggiornamento della chiamata in 'getDefaultRealm' funziona anche per i miei test correnti, quindi non sono sicuro di quanto sia necessario richiamare l'aggiornamento sullo sfondo. – Andrew