2009-08-05 8 views
14

Attualmente sto scrivendo un'applicazione Iphone utilizzando Core Data e ottengo un errore EXC_BAD_ACCESS durante la riga di codice [managedObjectContext save: & &]. Questo arresto si verifica solo dopo aver modificato determinati campi. Più specificamente la mia entità ha due campi stringa (su circa 10 campi), che ottengono i loro valori da un ritorno di un controller di visualizzazione modale (come un editor di testo). Lo schianto si verifica anche dopo che questi campi sono stati modificati, la prima volta che inserisco un valore in esso funziona correttamente.Iphone Core Dati in crash su Save

Il motivo per cui ho una stringa con i costruttori di formato con solo stringhe è perché stavo cercando di copiare il costrutto ... non sono sicuro che ciò avvenga automaticamente? Il pensiero forse conserva/rilascia messaggi da quelle stringhe (questi due sono dal controller modale), sono stati rilasciati in seguito al licenziamento del controller modale o qualcosa del genere. Indovina, però, perché ancora non funziona.

Ecco la sezione di codice che viene blocca:

[Modificato]

 - (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex: (NSInteger)buttonIndex 
     switch(buttonIndex) { 
       case 0: { 
       if(message == nil) { 
        message = [NSEntityDescription insertNewObjectForEntityForName:@"MailMessage" inManagedObjectContext:self.managedObjectContext]; 
       } 
       message.toString = txtTo.text; 
       message.fromString = txtFrom.text; 
       message.subjectString = txtSubject.text; 
       message.backgroundColor = [NSNumber numberWithInt:[bgColor intValue]]; 
       message.textArray = [NSString stringWithFormat:@"%@", stringTextArray]; 
       message.htmlString = [NSString stringWithFormat:@"%@", stringHTML]; 
       message.timeStamp = [NSDate date]; 
       message.statusCode = [NSNumber numberWithInt:0]; 
       NSError *error = nil; 
       if (![message.managedObjectContext save:&error]) { 
        abort(); 
       } 
       break; 
       } 
       case 1: { 
      break; 
       } 
     } 
     if(buttonIndex != modalView.cancelButtonIndex) { 
     [webViewBody loadHTMLString:@"<html><head></head><body></body></html>" baseURL:[NSURL URLWithString:@""]]; 
     [self.navigationController popToRootViewControllerAnimated:YES]; 
} 

}

Ed ecco il registro blocchi:

 
Exception Type: EXC_BAD_ACCESS (SIGBUS) 
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000015 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib     0x30011940 objc_msgSend + 20 
1 CoreData      0x367f7d3e -[NSKnownKeysDictionary1 dealloc] + 82 
2 CoreData      0x367f7cda -[NSKnownKeysDictionary1 release] + 34 
3 CoreData      0x3687eec4 -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] + 40 
4 CoreData      0x36821030 -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] + 16 
5 CoreData      0x368205f2 -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] + 958 
6 CoreData      0x368133bc -[NSManagedObjectContext save:] + 412 
7 Decome       0x0001fdd6 -[CreateMessageViewController actionSheet:clickedButtonAtIndex:] (CreateMessageViewController.m:163) 
8 UIKit       0x30a6cbd8 -[UIActionSheet(Private) _buttonClicked:] + 256 
9 CoreFoundation     0x30256dd4 -[NSObject performSelector:withObject:withObject:] + 20 
10 UIKit       0x3096e0d0 -[UIApplication sendAction:to:from:forEvent:] + 128 
11 UIKit       0x3096e038 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32 
12 UIKit       0x3096e000 -[UIControl sendAction:to:forEvent:] + 44 
13 UIKit       0x3096dc58 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 528 
14 UIKit       0x309a6e9c -[UIControl touchesEnded:withEvent:] + 452 
15 UIKit       0x309a60d4 -[UIWindow _sendTouchesForEvent:] + 520 
16 UIKit       0x309a5464 -[UIWindow sendEvent:] + 108 
17 UIKit       0x30936e3c -[UIApplication sendEvent:] + 400 

Ogni aiuto è apprezzato, Grazie .

AGGIORNAMENTO: Inoltre, anche se il programma si arresta in modo anomalo, quando apro il backup, i dati sono stati salvati correttamente. Quindi l'EXC_BAD_ACCESS deve avvenire dopo che il salvataggio è diventato abbastanza lontano da poter essere memorizzato nell'archivio persistente.

Se commento la riga di salvataggio, il codice funziona correttamente ora. Ma non salva dopo la chiusura e l'uscita. Se eseguo la riga di salvataggio nella mia funzione WillAppear di Root View Controller, genera lo stesso errore EXC_BAD_ACCESS. La console non dice altro che EXC_BAD_ACCESS se faccio un backtrace ottengo:

 
#0 0x30011940 in objc_msgSend() 
#1 0x367f7d44 in -[NSKnownKeysDictionary1 dealloc]() 
#2 0x367f7ce0 in -[NSKnownKeysDictionary1 release]() 
#3 0x3687eeca in -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:]() 
#4 0x36821036 in -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:]() 
#5 0x368205f8 in -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges]() 
#6 0x368133c2 in -[NSManagedObjectContext save:]() 
#7 0x0000314e in -[RootViewController viewWillAppear:] (self=0x11b560, _cmd=0x3014ecac, animated=1 '\001') at /Users/inckbmj/Desktop/iphone/Decome/Classes/RootViewController.m:85 

Spiacenti il ​​codice non è stato formattato correttamente prima. Quando questo controller della vista viene creato se non è un "messaggio" nuovo si passa un oggetto messaggio ottenuto da un fetchedResultsController in questo modo:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    MailMessage *aMessage = (MailMessage *)[fetchedResultsController objectAtIndexPath:indexPath]; 
    [messageView loadMessage:aMessage viewOnly:NO usingTemplate:NO]; 
    messageView.managedObjectContext = self.managedObjectContext; 
    [self.navigationController pushViewController:messageView animated:YES]; 
} 

(la prima serie di codice è dal file MessageViewController.m che è la classe che messsageView è)

Arresta in modo anomalo solo se si presenta il mio EditorViewController come vista modale e quindi si ritorna. Anche se cambio il textArray e linee htmlString (che sono le uniche cose che la vista modale colpisce) a:

message.textArray = @"HELLO"; 
message.htmlString = @"HELLO"; 

si blocca ancora. Se commento entrambe le righe ma non si blocca.

Quindi sembra che si blocca se presento una vista modale e quindi provo a modificare i campi textArray o htmlString del mio NSOManagedObject ...

Ecco dove presento la vista:

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event { 
    if(!viewOnly) { 
     UITouch *touch = [touches anyObject]; 
     CGPoint location = [touch locationInView: txtTo]; 
    location = [touch locationInView: webViewBody]; 
     if(CGRectContainsPoint(webViewBody.bounds, location)) { 
      [editor loadTextArrayString:stringTextArray]; 
      [self presentModalViewController:editor animated:YES]; 
     } 
    } 
} 

e dove i respingerlo:

-(void)returnWithTextArray:(NSString *)arrayString HTML:(NSString *)html bgColor:(NSNumber *)numColor { 
    [self dismissModalViewControllerAnimated:YES]; 
    self.stringTextArray = [NSString stringWithFormat:@"%@", arrayString]; 
    self.stringHTML = [NSString stringWithFormat:@"%@", html]; 
    self.bgColor = [NSNumber numberWithInt:[numColor intValue]]; 
    [webViewBody loadHTMLString:self.stringHTML baseURL:[NSURL URLWithString:@""]]; 
} 
+0

forse si può commentare alcuni dei cambiamenti nei vostri attributi prima, e provarli one by-one, per vedere quale causa l'arresto dopo aver cambiato e salvato. – digdog

+0

Non sembra essere causato da nessuno dei campi, penso che debba essere dovuto alla presentazione della vista modale ... Ma non ho idea del perché. Tutto quello che sto facendo è presentare la vista e poi chiuderla ... – kiyoshi

+0

Penso che potresti guardare nell'area sbagliata. 1. Commenta TUTTO il codice di salvataggio dei dati di base sopra. o semplicemente aggiungi una chiamata "return" nella parte superiore in modo che questo codice non venga mai eseguito. TEST per Crash. 2. Se l'arresto anomalo non si verifica, OK, deve essere nei dati principali. Fai tutto, ma non chiamare la funzione di salvataggio, ultime poche righe. 3. Mostraci l'intera quantità di codice per questa funzione poiché mi chiedo come stai compilando il messaggio se non è zero. 4. Che cosa dice la console.Dovrebbe darti qualche altro dettaglio su quello che è successo. –

risposta

8

Risolto il problema anche se non sono sicuro che sto affrontando l'effettiva causa principale. L'errore è stato eliminato quando ho aggiunto questa linea:

[managedObjectContext setRetainsRegisteredObjects:YES]; 

Per cui creo la managedObjectContext. Quindi immagino che abbia a che fare con i conti di mantenimento. Immagino che forse le variabili di istanza vengano rilasciate parzialmente o temporaneamente o qualcosa quando vengono visualizzate le visualizzazioni modali? Non lo so. In ogni caso, questo errore è stato eliminato e ora il programma funziona correttamente.

+0

Sto avendo un problema simile - anche risolto con la direttiva che hai incluso qui. Quello che non so è ... ci aspettiamo ora di rilasciare manualmente ogni entità gestita da questo moc? –

+1

Anche se questo potrebbe correggere il tuo problema, il tuo ragionamento è un po 'difettoso La mia risposta qui sotto spiega perché salva: sta causando il tuo problema e punta ai documenti Apple. –

+0

Ciao. gli oggetti gestiti non salvati vengono rilasciati quando si chiama save.I nuovi oggetti gestiti devono essere caricati dal controller dei risultati di recupero. – stephen

0

Ho visto molti comportamenti divertenti con CoreData su iPhone che sono stati risolti reimpostando contenuto e le impostazioni nel simulatore di iPhone.

+0

Anche se funziona su un ipod touch, ma sì ha provato a ripristinare il contenuto senza alcun risultato :(. – kiyoshi

0

So che questo è un vecchio, ma ho avuto lo stesso problema, quindi ho pensato di aggiungere il mio punto su come ho risolto il problema, il mio è stato causato rilasciando manualmente l'oggetto gestito all'interno della vista modale, ho rimosso il rilascio chiama e tutto funziona bene :) secondo i documenti non dovresti provare e rilasciare manualmente gli oggetti gestiti comunque, dato che il contesto si occuperà di tutto ciò. Questa è comunque la mia esperienza, cerca nel tuo codice per i valori sovra-rilasciati.

0

È necessario impostare la cache FRC a zero

4

Proprio per aiutare gli altri che hanno lo stesso problema, e rafforzando la risposta di Steff sopra, la probabile causa di questo errore è che si sta cercando di rilasciare una NSManagedObject.

22

Si garantisce solo a mantenere l'accesso a un oggetto gestito dal contesto fintanto che una modifica è in sospeso su tale oggetto (inserire, aggiornare, eliminare). Non appena effettui una chiamata per salvare: puoi perdere il tuo riferimento all'oggetto gestito.

Mentre si interrompe l'errore quando si imposta setRetainsRegisteredObjects: YES, è possibile che sia stato introdotto un problema di gestione della memoria, poiché si imposta la durata dell'oggetto gestito per dipendere dalla durata del contesto dell'oggetto gestito. Se passi il contesto attorno alla tua app, questo potrebbe diventare piuttosto grande se hai una gerarchia di oggetti di grandi dimensioni.

Puoi leggere ulteriori informazioni nei documenti Apple qui: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMemory.html.

0

ho risolto un problema simile facendo in modo che l'oggetto viene recuperata, così per l'esempio precedente:

if (message == nil) { 
    message = [NSEntityDescription insertNewObjectForEntityForName:@"MailMessage" inManagedObjectContext:self.managedObjectContext]; 
} else { 
    NSError *error = nil; 
    message = (MailMessage *)[managedObjectContext existingObjectWithID:[message objectID] error:&error]; 
}