2016-01-19 25 views
9

Sto usando Realm per la mia app, voglio poter interrogare i risultati su un thread in background e riceverli su il thread principale. Qual è il modo migliore per raggiungere questo obiettivo? e qual è la migliore pratica per usare il realm (avendo un metodo diverso per main thread e background? e in main usando un'istanza statica di realm attraverso l'app? forse un altro buon modo?)Realm: il modo giusto per aggiungere, aggiornare, rimuovere operazioni dal thread in background e ottenere risultati sul thread principale

Ho letto e visto queste opzioni sono disponibili: - analizzando l'oggetto realm sul mio oggetto e restituendoli (una specie di copia dei risultati). - Restituisce una chiave dell'oggetto e esegue nuovamente una query dal thread principale.

Grazie per l'aiuto che chiunque può darmi, penso davvero che il regno abbia un grande potenziale ma c'è una mancanza di buoni tutorial e buone pratiche.

risposta

6

In primo luogo, dal momento che il reame è abbastanza veloce nella maggior parte dei casi, non è necessario eseguire una query in background.

Quindi la strategia di base è; aggiorna in background, recupera il thread principale.

Il modo più generale è sfruttare la funzionalità dell'aggiornamento dal vivo. RLMResults e Results hanno un aggiornamento dal vivo. È possibile mantenere le istanze RLMResults/Results tramite query. Quindi apporterai eventuali modifiche al thread in background, le modifiche verranno notificate e riflesse automaticamente al momento del commit.

// Hold RLMResults for the data source 
self.array = [[DemoObject allObjects] sortedResultsUsingProperty:@"date" ascending:YES]; 

// Reload table view when changed by other threads 
__weak typeof(self) weakSelf = self; 
self.notification = [RLMRealm.defaultRealm addNotificationBlock:^(NSString *note, RLMRealm *realm) { 
    [weakSelf.tableView reloadData]; 
}]; 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    // RLMResults is updated automatically 
    return self.array.count; 
} 

// Update in background 
- (void)backgroundAdd 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    // Import many items in a background thread 
    dispatch_async(queue, ^{ 
     // Get new realm and table since we are in a new thread 
     RLMRealm *realm = [RLMRealm defaultRealm]; 
     [realm beginWriteTransaction]; 
     for (NSInteger index = 0; index < 5; index++) { 
      // Add row via dictionary. Order is ignored. 
      [DemoObject createInRealm:realm withValue:@{@"title": [self randomString], 
                 @"date": [self randomDate]}]; 
     } 
     [realm commitWriteTransaction]; 
    }); 
} 

Per maggiori dettagli, si può vedere il table view example in Realm's repo.

Se in alcuni casi Realm non è abbastanza veloce durante il recupero sul thread principale, è possibile recuperare il thread in background. Quindi aggregare una matrice di chiavi primarie. Quindi passa la matrice e recupera nuovamente il thread principale utilizzando le chiavi primarie.

FYI: Stiamo lavorando per aggiungere il supporto per l'esecuzione di query in modo asincrono https://github.com/realm/realm-cocoa/pull/2842 Se questa funzione sarà rilasciato, non è necessario per aggregare le chiavi primarie e ri-fetch.

+1

Cosa mi dici di analizzare gli oggetti del regno nei miei oggetti veloci e di restituirli? ci vorrà più tempo per riprendersi? e un'altra domanda, che dire dell'uso di realm sul thread principale, qual è la migliore pratica per ottenere l'istanza di realm? dovrei inserire un'istanza statica nel delegato di app o altrove e utilizzare questo riferimento ovunque mi serva o creare riferimenti di realm in ogni luogo in cui voglio ottenere i dati? –

+0

E riguardo gli aggiornamenti? Se provo a eseguire un aggiornamento in un thread in background usando gli oggetti che ho letto nel thread principale ottengo questa eccezione: 'Non posso aggiungere oggetti da un diverso Realm' – Ixx

+0

@Ixx Stai fraintendendo come usare il Realm. L'oggetto Realm non può passare ad altri thread, inoltre non può aggiungere oggetti da un Reame diverso. Dovresti creare un'istanza di Realm su ciascun thread e recuperare gli oggetti di Realm. Tuttavia, gli oggetti Realm sono live, aggiornati automaticamente. Quindi la best practice è interrogare sul thread principale, quindi scrivere thread in background. Gli oggetti Realm sono attivi, non è necessario ri-interrogare. –