2010-10-14 11 views
18

ottengo il seguente errore quando si tenta di aggiungere un record:Grave Applicazione Errore nei dati di core con fetchedResultsContainer

errore dell'applicazione grave. L'eccezione è stata rilevata durante l'elaborazione di Modifica dati principali . Questo è di solito un errore all'interno di un osservatore di NSManagedObjectContextObjectsDidChangeNotification. L'indice 0 è valido con userInfo (null)

E questo è tutto. Metto i punti di interruzione in tutti i metodi di delegato Recuperati con Resontainer che ho implementato, ma non si rompe nulla.

ho rintracciato giù a:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"titleFirstLetter" cacheName:@"Root"]; 

"sectionNameKeyPath" è il problema. "titleFirstLetter" è una proprietà temporanea che ho creato un getter per la sottoclasse NSManagedObject.

Ecco il getter:

-(NSString *)titleFirstLetter 
{ 
    [self willAccessValueForKey:@"titleFirstLetter"]; 
    NSString *aString = [[self valueForKey:@"title"] uppercaseString]; 

    NSString *stringToReturn = [aString substringWithRange:[aString rangeOfComposedCharacterSequenceAtIndex:0]]; 

    [self didAccessValueForKey:@"titleFirstLetter"]; 
    return stringToReturn; 
} 

quando cambio la sectionNameKeyPath a zero, funziona, ma ovviamente non è quello che voglio. Funziona anche quando ho un titolo già compilato per il mio modello, in modo che titleFirstLetter non restituisca nil, anche se questo non sembra essere il problema. Se trasformo la stringa in qualcosa di arbitrario se è nulla, si blocca ancora.

Qualche idea di cosa c'è qui?

AGGIORNAMENTO: Se utilizzo il titolo in sectionNameKeyPath anziché nella proprietà transiente, non si blocca, ma ovviamente inserisce ogni elemento nella propria sezione. Quindi è in qualche modo correlato alla proprietà transitoria ...

UPDATE2: Un po 'di hacking preliminare con l'uso di una proprietà persistente invece di transiente, e nessun'altra modifica, sembra funzionare bene, quindi questo sembra essere un bug. Ho un bug report aperto: # 8553064

UPDATE3: Beh, grattalo. L'uso di un attributo persistente non ha fatto alcuna differenza. Sono un po 'alla fine dei colpi ora.

Grazie!

risposta

12

Bene, questo è probabilmente in parte (o completamente) l'errore dell'utente. Il problema era che, nella vista in cui aggiungevo un nuovo oggetto, avevo inserito [self.tableView reloadData] all'interno del metodo viewWillAppear. Commentandolo non ha aggiornato le celle della tabella, ma ha impedito il crash.

Poi sono andato avanti e ho inviato reloadRowsAtIndexPaths:withRowAnimation: alla vista tabella per ricaricare manualmente le poche celle che ne avevano bisogno.

Sono contento che sia finalmente finita!

+0

Salvato il mio bacon! Grazie! Dove hai aggiunto reloadRowsAtIndexPaths: withRowAnimation :? –

+0

molto grazie. questo problema mi infastidisce per molto tempo. – derjohng

2

Il comportamento predefinito del controller dei risultati recuperati consiste nel creare una sezione per ogni prima lettera di sectionNameKeyPath. Non dovresti ottenere una sezione per articolo a meno che ogni articolo inizi con una lettera diversa.

Se si desidera personalizzare il comportamento del nome della sezione, sottoclasse NSFetchedResultsController e sovrascrivere sectionIndexTitleForSectionName: e sectionIndexTitles. Vedere i documenti NSFetchedResultsController per i dettagli.

+0

Quindi cosa sto facendo di sbagliato qui? http://assets.zerodeviation.net/sections.png Questo è con il titolo come sectionNameKeyPath. – Christoph

+0

Per aggiungere a questo, i documenti dicono che __IndexTitle__ è di default la prima lettera maiuscola. E questo è vero. Ma sto parlando dei titoli delle sezioni. – Christoph

+0

ITitoliTitoli sono i titoli delle sezioni. Guarda come i nomi degli elenchi delle app di contatto. Usa questo metodo esatto incorporato. Non so perché hai avuto questo problema. Molto probabilmente hai un incrocio tra gli attributi. – TechZen

1

Ho scoperto un altro modo per arrivare a questa stessa eccezione criptica. La mia proprietà transitoria, come la tua, per estrarre la prima lettera, non era protetta da una stringa di lunghezza 0 (@ ""). Il tentativo di ottenere il suo primo personaggio ha generato un'eccezione e ha provocato questo errore di Core Data (e non l'eccezione che ci si aspetterebbe di vedere).

2

Ho pensato che questo era il mio problema. Avevo lo stesso messaggio di avvertimento, ma la mia soluzione era MOLTO diversa.

È possibile ottenere questo errore se non sono stati implementati correttamente tutti i metodi del delegato NSFetchedResultsController. Ho sempre solo copiato e incollato i 4 metodi di Apple per come implementare NSFetchedResultsController.

Purtroppo avevo perso uno di questi:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView beginUpdates]; 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 

assicurati di aver GOT EM, altrimenti si tira fuori i capelli come me.

+0

Terrò d'occhio per quelli, grazie! – Christoph

+0

Questa è una soluzione molto semplice a un problema comune. Anche se tutte le altre risposte sono sicure, anche questo sottile errore può generare lo stesso errore. Vale la pena notare. –

0

Importante

NSFetchedResultsController * consultMessageFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[[WYCoreDataStorage shareStore] coreDataHelper] mainContext] sectionNameKeyPath:nil cacheName:nil]; 

Se si utilizza una cache, è necessario chiamare deleteCacheWithName: prima di modificare qualsiasi della richiesta fetch, suo predicato, o le sue descrittori di ordinamento. Non è possibile riutilizzare lo stesso controller dei risultati recuperato per più query a meno che non si imposti nil su cacheName.

Problemi correlati