2010-02-11 6 views
5

Sto utilizzando un NSFetchedResultsController per gestire la visualizzazione degli oggetti gestiti recuperati in una vista tabella che ha una sezione. La tabella inizia vuota e l'utente può aggiungere nuove entità utilizzando l'interfaccia utente. Così com'è, il programma funziona sempre quando si aggiunge la prima entità e si blocca sempre quando si aggiunge un secondo. A volte non si presenta alcun errore in caso di crash e altre volte ci sono errori di tipi diversi (alcuni inclusi di seguito). Attraverso le istruzioni e la traccia del log vedo che il programma si blocca subito dopo che il controller del delegato di NSFetchResultsControllerWillChangeContent (che chiama [self.tableView beginUpdates];) esce dal metodo, ma prima che venga chiamato qualsiasi altro metodo nel mio codice. Ecco alcune delle parti del mio codice che rilevano. Configurazione del NSFetchedResultsController:NSFetchedResults La vista tabella basata sul controllore fallisce sempre al SECONDO inserimento dell'entità

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Beer" 
            inManagedObjectContext:self.managedObjectContext]]; 

// Configure request's entity and predicate 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 
[sortDescriptor release]; 
[sortDescriptors release]; 

NSString *expression = [NSString stringWithFormat:@"brewery.name LIKE \"%@\"", self.brewery.name]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:expression]; 
[fetchRequest setPredicate:predicate]; 
self.resultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                  managedObjectContext:self.managedObjectContext 
                   sectionNameKeyPath:nil 
                     cacheName:nil]; 
self.resultsController.delegate = self; 
[fetchRequest release]; 

NSError *error = nil; 
BOOL success = [resultsController performFetch:&error]; 
if (!success) { 
    NSLog(@"Error fetching request %@", [error localizedDescription]); 
} 

Aggiunta nuova entità:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Beer" inManagedObjectContext:self.managedObjectContext]; 
Beer *beer = [[Beer alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext]; 
beer.name = beerName; 
beer.brewery = self.brewery; 

Ho visto le avvertenze nella documentazione sui problemi che espongono le tabelle con una sezione, e ho usato soluzione di Apple per questo senza alcun risultato. Comunque, quei metodi non vengono chiamati prima dello schianto.

Alcuni degli errori che ho ricevuto:

Serious application error. Exception was caught during Core Data change processing: *** -[NSCFString compareObject:toObject:]: unrecognized selector sent to instance 0x4e808c0 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[CALayer compareObject:toObject:]: unrecognized selector sent to instance 0x4e53b80 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[UITextTapRecognizer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4ca5d70 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[CALayer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4e271a0 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[NSCFNumber countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x4c96ee0 with userInfo (null) 

Come si può vedere, gli errori (quando uno è stato presentato) non sono coerenti, anche in assenza di modifica al codice è stato fatto.

Qualcuno può capire cosa sto facendo male?

+0

Ho esattamente lo stesso errore. Puoi dirmi cosa hai fatto per risolvere il problema? Grazie. – zsong

risposta

4

Gli errori incoerenti indicano un possibile problema di sovradimensionamento. Soprattutto perché cambiare i tuoi delegati per ricaricare i dati fa andare via il problema. Personalmente avrei investito il tempo necessario per risolvere il problema, piuttosto che doverlo codificare in quanto sicuramente avresti un problema di codice che probabilmente si presenterà più tardi da qualche altra parte.

vorrei fare le seguenti operazioni:

  1. Accendere NSZombie
  2. Aggiungere un punto di interruzione per objc_exception_throw
  3. Run nel debugger

Quando si verifica l'eccezione, guardo l'indirizzo di memoria e vedere a cosa viene acceduto e dove. Questo isolerà il problema e ti dirà cosa sta succedendo. Sarebbe anche utile, se questo non rivela il problema, di inviare i tuoi metodi di delega in modo da poter vedere se c'è qualcosa di strano in loro.

È consigliabile aggiornare la domanda originale con le informazioni aggiuntive.

1

Il codice per creare nuove entità è tutto strano. Cosa succede ad usare questo invece:

Beer* beer = [NSEntityDescription insertNewObjectForEntityForName: @"Beer" 
    inManagedObjectContext: self.managedObjectContext]; 
beer.name = @"Grolsch"; 

Inoltre, non sta chiamando NSManagedObjectContext#save:. Ma forse lo stai facendo in una parte del tuo codice che ora hai mostrato?

+0

I due metodi per la creazione della nuova entità sono equivalenti. Dove viene salvato anche il ManagedObjectContext non ha alcun effetto sul problema. –

1

Anche se non ho risolto questo particolare problema, ho adottato un approccio leggermente diverso rispetto alla scrittura della classe che ha fornito la funzionalità desiderata e non ha causato il problema. Sto ancora utilizzando NSFetchedResultsController, ma invece di implementare tutti e quattro i metodi delegate, sto solo implementando controllerDidChangeContent :, che chiama semplicemente [tableView reloadData].

Questa è l'implementazione inclusa nella classe RootViewController se si crea una nuova applicazione di navigazione in XCode che utilizza i dati principali per l'archiviazione. Probabilmente perdi il controllo sulle animazioni di modifica delle tabelle, ma è più semplice e funziona perfettamente per i miei scopi.

0

Questo è vecchio ma a beneficio di altri che hanno lo stesso problema, ho passato ore a cercare di capire cosa stava succedendo e ho finalmente trovato un problema con il mio descrittore di ordinamento che causava questi arresti casuali.

I messaggi di errore variavano ma erano per lo più correlati a un oggetto comparatore: toObject come di seguito.

- [_ NSCFSet compareObject: ToObject:]: selettore non riconosciuto inviato ad esempio - [ _NSCFString compareObject: ToObject:] selettore non riconosciuto inviato ad esempio

Il mio suggerimento è quello di cercare di eliminare tutti i descrittori di ordinamento e predicati dal tuo codice e quindi aggiungili uno per uno per trovare dove si trova il problema.

Buona fortuna! Rog

1

ho avuto un bug simile di recente - il problema è con il rilascio, in particolare:

[sortDescriptors release]; 

È possibile ottenere i sortDescriptors oggetto da

[NSArray arrayWithObjects:sortDescriptor, nil]; 

che non ha "alloc" , "copia" o "nuovo", quindi restituisce un oggetto autoreleased. Poiché lo si rilascia presto, si ottengono due punti in cui è possibile arrestarsi in modo anomalo, quando NSFetchRequest lo utilizza e quando viene rilasciato dal pool. Vedi apple memory management guide per maggiori dettagli.

Problemi correlati