Domanda

Ho un NSFetchedResultsController come la mia fonte di dati ed e implemento NSFetchedResultsControllerDelegate nella mia abitudine UITableViewController. Sto usando sectionNameKeyPath di rompere il mio set di risultati in più sezioni.

In uno dei miei metodi, io sono l'aggiunta di un paio di oggetti al contesto, che sono tutti in una nuova sezione. Al momento in cui risparmio il gli oggetti, i metodi delegato vengono chiamati in modo corretto. L'ordine degli eventi:

// -controllerWillChangeContent: fires
[self.tableView beginUpdates]; // I do this

// -controller:didChangeSection:atIndex:forChangeType: fires for section insert
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];

// -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath fires many times
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                withRowAnimation:UITavleViewRowAnimationFade]; // for each cell

// -controllerDidChangeContent: fires after all of the inserts
[self.tableView endUpdates];  // <--- Where things go terribly wrong!!!

L'ultima chiamata, "endUpdates", l'applicazione si blocca sempre con:

Serious application error.  Exception was caught during Core Data change processing:
[NSCFArray objectAtIndex:]: index (5) beyond bounds (1) with userInfo (null)

Sembra che gli aggiornamenti della tabella non sono sincronizzati con i dati NSFetchedResultsController in qualche modo, e le cose saltare in aria. Sto seguendo la documentazione su NSFetchedResultsControllerDelegate, ma non sta funzionando. Qual è il modo giusto per farlo?

UPDATE: Ho creato un progetto di test che presenta questo bug. Potete scaricarlo all'indirizzo: NSBoom.zip

È stato utile?

Soluzione

Tracing attraverso l'applicazione, rilevo didChangeSection viene chiamato per primo, che inserisce una sezione intera -. E poi didChangeObject si chiama più volte

Il problema è che in didChangeSection si inserisce una sezione intera, poi a destra dopo prima che la vista tabella viene aggiornata si sta aggiungendo oggetti alla stessa sezione. Questo è fondamentalmente un caso di sovrapposizione aggiornamenti ... (non ammessi anche in un inizio / fine blocco aggiornamenti).

Se si commento l'inserto singolo oggetto, tutto funziona:

 case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

Se si commento fuori l'inserto sezione :, che non funziona - ma ho avuto meno fortuna con insertRowsInSections di lavoro per tutto il tempo, e può ben essere perché non c'è ancora la sezione (che sono sicuro che è il motivo per stavate inserendo la sezione per cominciare). Potrebbe essere necessario rilevare entrambi i casi a che fare con la granularità inserti destra.

In generale ho avuto molta più fortuna ricaricare e l'inserimento di intere sezioni di file, la visualizzazione della tabella sembra molto poco pratici a me in giro coloro che lavorano. Si può anche provare UITableViewRowAnimationNone che sembra operare con successo più spesso.

Altri suggerimenti

Sto avendo lo stesso problema. Trovo che didChangeSection spara due volte. Una volta, quando si crea l'oggetto per l'inserimento, e una volta quando in realtà salva. Per me, non dovrebbe chiamare didChangeSection fino Salva viene chiamato. O per lo meno, willChangeSection sarebbe chiamato sulla creazione dell'oggetto, e didChangeSection chiamato quando viene salvato.

Ora sto esaminando il metodo osservatore NSManagedObjectContextDidSaveNotification. Questo non è parte del protocollo NSFetchedResultsControllerDelegate, ma è possibile registrarsi per ricevere esso. Forse questo sarà chiamato solo quando ho effettivamente chiama Salva e non prima.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top