2009-08-05 15 views
14

Actualmente estoy escribiendo una aplicación para Iphone usando Core Data y me sale un error EXC_BAD_ACCESS durante la línea de código [managedObjectContext save: & &]. Este bloqueo solo ocurre después de modificar ciertos campos. Más específicamente, mi entidad tiene dos campos de cadena (de alrededor de 10 campos), que obtienen sus valores de un retorno de un controlador de vista modal (como un editor de texto). El bloqueo solo ocurre después de que se editan estos campos, la primera vez que pongo un valor funciona bien.Iphone Core Data se bloquea al guardar

La razón por la que tengo una cadena con constructores de formato con solo cadenas es porque estaba tratando de copiar la construcción ... ¿no estoy seguro de que eso ocurra automáticamente? Pensé que tal vez retener/liberar mensajes de esas cadenas (esos dos son del controlador de vista modal), que se liberaban al descartar el controlador de vista modal o algo así. Adivina aunque no porque todavía no funciona.

Aquí está la sección de código que está fallando:

[Editado]

 - (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]; 
} 

}

Y aquí está el registro de bloqueo:

 
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 

se aprecia cualquier ayuda, gracias .

ACTUALIZACIÓN: Además, aunque el programa se cuelga, cuando lo abro, los datos se guardaron correctamente. Por lo tanto, el EXC_BAD_ACCESS debe ocurrir después de que el guardado haya llegado al menos lo suficiente como para almacenarlo en la tienda persistente, creo.

Si comento la línea de guardado, el código funciona bien ahora. Pero no se guarda después de cerrar y salir. Si ejecuto la línea de guardado en mi función Root View Controllers willAppear, arroja el mismo error EXC_BAD_ACCESS. La consola no decir aparte de EXC_BAD_ACCESS nada si hago un trazado inverso consigo:

 
#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 

sentimos el código no se haya formateado correctamente antes. Cuando este controlador de vista se crea si no es un "mensaje" que se transmite de nuevo un objeto de mensaje obtenida de un fetchedResultsController así:

- (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]; 
} 

(el primer conjunto de código es del archivo que es MessageViewController.m la clase que messsageView es)

Solo se bloquea si presento mi EditorViewController como una vista modal y luego regreso. Incluso si cambio el TextArray y líneas htmlString (que son las únicas cosas que la vista modal) afecta a:

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

se vuelve a colgarse. Si comento ambas líneas, sin embargo, no se cuelga.

Parece que se bloquea si presento una vista modal y luego trato de editar los campos textArray o htmlString de mi NSOManagedObject ...

Aquí es donde me 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]; 
     } 
    } 
} 

y donde la desestimación que:

-(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

Tal vez usted puede comentar algunos de los cambios en sus atributos en primer lugar, y probarlos uno por uno, para ver cuál causa el colapso después de cambiar y guardar. – digdog

+0

No parece ser causada por cualquiera de los campos, creo que debe ser debido a la presentación de la vista modal ... Pero no tengo ni idea de por qué. Todo lo que hago es presentar la vista y luego descartarla ... – kiyoshi

+0

Creo que podría estar buscando en el área incorrecta. 1. comentario todas los datos básicos guardar código de seguridad. o solo agrega una llamada de "retorno" en la parte superior para que este código nunca se ejecute. PRUEBA para Crash. 2. Si no se produce el bloqueo, está bien, debe estar en los datos principales. Haga todo, pero no llame a la función de guardar, las últimas líneas. 3. Muéstrenos todo el código para esta función, ya que me pregunto cómo está rellenando el mensaje si no es nulo. 4. ¿Qué dice la consola?Debería darte más detalles sobre lo que sucedió. –

Respuesta

8

resuelto el problema, aunque no estoy seguro de que estoy abordando la causa raíz real. El error se eliminó cuando agregué esta línea:

[managedObjectContext setRetainsRegisteredObjects:YES]; 

Para donde creo managedObjectContext. Así que supongo que tiene que ver con retener conteos. Supongo que quizás las variables de instancia se liberen parcial o temporalmente o algo cuando se presentan vistas modales. No lo sé. En cualquier caso, este error fue eliminado, el programa funciona bien ahora.

+0

Tengo un problema similar, también corregido con la directiva que ha incluido aquí. Lo que no sé es ... ¿Esperamos que ahora liberemos manualmente todas las entidades administradas por este moc? –

+1

Si bien esto puede corregir su problema, su razonamiento es algo defectuoso. Mi respuesta a continuación explica por qué guardar: está causando su problema y apunta a los documentos de Apple. –

+0

Hola. los objetos administrados no guardados se liberan cuando se llama a guardar. Los nuevos objetos administrados se deben cargar desde el controlador de resultados de búsqueda. – stephen

0

he visto muchos comportamientos divertidos con CoreData en el iPhone que fueron resueltos por restablecer el contenido y los ajustes en el simulador de iPhone.

+0

Sin embargo, ejecutarlo con un ipod touch, pero sí intenté restablecer el contenido en vano :(. – kiyoshi

0

Sé que esto es un oldie pero tuve el mismo problema, así que pensé en agregar mi tuppence en cuanto a cómo resolví el problema, el mío fue causado al liberar manualmente el objeto administrado dentro de la vista modal, eliminé el lanzamiento llamadas y todo está funcionando bien :) acuerdo con los documentos que usted no debe tratar de liberar los objetos gestionados de todas formas, el contexto se verá después de todo esto manualmente. Esa es mi experiencia de todos modos, busca en tu código valores sobrevalorados.

0

Debe establecer el caché FRC a cero

4

Sólo para ayudar a otros con el mismo problema, y ​​el refuerzo de la respuesta de Steff anteriormente, la causa probable de este error es que usted está tratando de liberar una NSManagedObject.

22

Sólo están garantizados para mantener el acceso a un objeto administrado por el contexto, siempre que un cambio está pendiente a ese objeto (insertar, actualizar, eliminar). Tan pronto como realice una llamada para guardar :, puede perder su referencia al objeto administrado.

Mientras que dejó de obtener el error cuando configuró setRetainsRegisteredObjects: YES, puede haber introducido un problema de administración de memoria, ya que establece que la duración del objeto administrado depende de la duración del contexto del objeto administrado. Si pasa su contexto a través de su aplicación, esto podría ser bastante grande si tiene una jerarquía de objetos grande.

Usted puede leer más en la documentación de Apple aquí: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdMemory.html.

0

he resuelto un problema similar al asegurarse de que el objeto es exagerado, por lo que para el ejemplo anterior:

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