Ho un UITableView
(con celle personalizzate, se questo è importante) collegato a un NSFetchedResultsController
. La mia app utilizza anche notifiche push. Quando arriva una notifica remota, aggiorno il mio modello di dati (principale) in due fasi:NSFetchedResultsController ritardo coerente nell'aggiornamento della cella UITableView; inserire funziona immediatamente
1) Ottieni titolo (con alcuni dati personalizzati) e memorizzalo come nuovo core data Entity
. Qui chiamo NSManagedObjectContext save()
. NSFetchedResultsController
preleva l'inserto e attiva il suo metodo delegato didChangeObject
con NSFetchedResultsChangeType
= NSFetchedResultsChangeInsert
. La tableview è immediatamente aggiornata. (È stata inserita una nuova riga)
2) Scaricare più contenuto correlato alla cella tramite NSURLSession
inseriscilo nello Entity
precedente e chiamare di nuovo lo save() method
. NSFetchedResultsController
recupera nuovamente l'aggiornamento e attiva il suo metodo delegato didChangeObject
con NSFetchedResultsChangeType
= NSFetchedResultsChangeUpdate
. È qui che chiamo il mio metodo configureCell
. Il TableView è aggiornato ma con un ritardo costante di circa 10 secondi.
In entrambe le fasi (download-contesto save-update tableview) i dati che devono essere mostrati sono stati già mantenuti dai dati principali. (Per esempio, all'interno mio metodo configureCell..
, io so che non sto impostando qualsiasi etichetta cella per nil
o simili
I miei metodi NSFetchedResultsController
delegato:.
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.mainTableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.mainTableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.mainTableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:(MessageTableViewCell *)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
}
}
Altre cose che ho provato dentro case NSFetchedResultsChangeUpdate:
- provato a chiamare
processPendingChanges
prima contestosave
- Chiamato
reloadRowsAtIndexPaths
invece di chiamareconfigureCell
direttamente - provato avvolgendo l'aggiornamento .. metodi all'interno
beginUpdates
eendUpdates
(anche se ho già un paio che dovrebbe fare il lavoro) [tableView reloadData]
numberOfRowsInSection
non è 0!- I metodi delegati
NSFetchedResultsController
vengono eseguiti solo sul thread principale.
In poche parole, tutti i (?) Metodi di delega appropriati vengono chiamati correttamente. Tuttavia, vedo un ritardo costante di circa 10 secondi durante l'aggiornamento di una cella. Tuttavia, l'inserimento avviene quasi istantaneamente. Qualche idea?
Non viene visualizzato il codice in cui si aggiorna la tabella dopo il completamento dell'operazione di rete, ma suppongo che non si stia inviando l'aggiornamento sulla coda principale. – Paulw11
Beh, se "inviando" l'aggiornamento, intendi chiamare 'save', quindi no, sto chiamando' save' dal metodo delegato 'NSURLSession'' URLSession: downloadTask: didFinishDownloadingToURL: 'che NON è sul thread principale se non erro? –
Quindi stai utilizzando un contesto thread di sfondo che hai creato e salvando le modifiche? – Wain