2010-09-12 12 views
6

lector ocasional y la primera pregunta que pregunta el tiempo, así que por favor ser suave :)Odd Core Error de datos causado por la liberación excesiva?

Estoy creando un Managed Object (Cuenta), que se pasa en un controlador de vista del niño en su conjunto está en una propiedad que es retenido

Account * account = [[Account alloc] initWithEntity:entity insertIntoManagedObjectContext:context]; 
AddAccountViewController *childController = [[AddAccountViewController alloc] init]; 
childController.title = @"Account Details"; 
childController.anAccount = account; 
childController.delegate = self; 

[self.navigationController pushViewController:childController animated:YES]; 
[childController release]; 
[account release]; 

La vista de la interfaz del controlador:

@interface AddAccountViewController : UIViewController { 
} 

@property (nonatomic, retain) IBOutlet UITextField * usernameTextField; 
@property (nonatomic, retain) IBOutlet UITextField * passwordTextField; 

@property (nonatomic, retain) Account * anAccount; 
@property (nonatomic, assign) id <AddAccountDelegate> delegate; 

- (IBAction)cancel:(id)sender; 
- (IBAction)add:(id)sender; 
- (IBAction)textFieldDone:(id)sender; 
@end 

Así, en el ejemplo de código 1 Me he lanzado el objeto de cuenta porque ya no estoy interesado en él en ese método. Como lo conserva el AddAccountViewController Tengo una entrada en AddAccountViewController 's dealloc que lo libera.

Sin embargo, cuando voy a eliminar el objeto de la ManagedObjectContext la aplicación se bloquea con el siguiente (en lugar claro) Error:

Detected an attempt to call a symbol in system libraries that is not present on the iPhone: 
_Unwind_Resume called from function _PFFaultHandlerLookupRow in image CoreData. 

Después de mucha depuración & tirar del pelo descubrí que si no lo hago liberar cuenta en AddAccountViewControllerdealloc método la aplicación funciona correctamente de forma continua y no parece tener fugas según los instrumentos.

¿Alguien puede arrojar alguna luz sobre qué está pasando? Entiendo por los documentos sobre las propiedades que los que se retienen deben ser liberados. ¿Qué me he perdido?

actualización para responder a la pregunta de Kevin

El código para eliminar el objeto de la ManagedObjectContext está en el RootViewController (que sostiene el controlador niño)

// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the managed object for the given index path 
     NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 

     [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

     // Save the context. 
     NSError *error = nil; 
     if (![context save:&error]) { 
      /* 
      Replace this implementation with code to handle the error appropriately. 

      abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
      */ 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
    } 
} 
+0

¿Puede mostrar el código que lo elimina del NSManagedObjectContext? ¿Y sucede esto dentro de AddAccountViewController o en otro lugar? –

+0

'childController.anAccount = account;' esta línea NO retiene 'account'. Lo copia a 'una Cuenta'. Esto no retiene +1 en absoluto, y solo tendrá que liberar 'anAccount' en el método dealloc 'AddAccountViewcontroller'. –

+0

@Thomas: '@property (nonatomic, retain) Cuenta * anAcount;' ¿Por qué no retendrá? – Pyetras

Respuesta

1

En primer lugar: Suena como un error por parte de Apple. Core Data llama al _Unwind_Resume, que es (probablemente) algún tipo de excepción. Excepción-desenrollar existe en el teléfono, pero (creo) utiliza ARM ABI, que utiliza nombres de funciones que comienzan con __cxa_. ¿Estás corriendo en el simulador? ¿Qué versión del SDK?

Puede haber una versión extra flotando en algún lugar que está "equilibrada" cuando quita la llamada a [account release];.

"Los instrumentos no muestran ninguna fuga" no significa que no haya ninguno; La última vez que lo revisé se confundió por ciclos (es decir, no mostraría una fuga si olvidó desasociar IBOutlets en dealloc). Probé con NSMutableData * d = [NSMutableData dataWithLength:1<<20]; memcpy(d.mutableBytes, &d, 4);, pero una prueba más fácil es solo [[UIView alloc] initWithFrame:CGRectZero].

Si crees que es un problema de retención/liberación, una vez depuré estos sobrescribiendo retener/liberar/liberar automáticamente para llamar a NSLog. Luego agregué puntos de interrupción en todos ellos, los configuré para que ejecutaran el comando "bt", y hice clic en el autocontinuar. Luego ejecute lo que se rompe (en mi caso, creo que fue solo un retenedor extra), imprima el resultado de registro, péguelo en una pizarra y dedique media hora a la combinación de retenciones y lanzamientos.

+1

De hecho, al eliminar el '[release de la cuenta];' al final del primer bloque significa que 'retener' y' liberar' en 'AddAccountViewController' se equilibran correctamente y la aplicación no se bloquea al guardar después de eliminar una entrada del' ManagedObjectContext'. En cuanto a la primera parte, estaba ejecutando el código en el simulador y el dispositivo y obteniendo ese error. El SDK era 4.1GM. – tarasis

+0

Si elimina '[account release];' como se describe lo arregla, entonces AddAccountViewController se rompe (con respecto a las convenciones de administración de memoria de Obj-C). No es fácil determinar dónde está roto sin mirar todo el código dentro de AddAccountViewController que toca la propiedad anAccount o su variable de instancia de respaldo. (Además, prefijando propiedades/ivars con "a" o "an" no está en ninguna convención de codificación que yo sepa, y contradice los lugares donde Apple lo usa). –

0

Cuando elimine cualquier managedobject, el sistema liberará automáticamente todas las referencias relacionadas con ese objeto. Por lo tanto, no es necesario ejecutar el objeto programáticamente. Una vez que elimine el objeto, no podrá acceder a ese objeto en la clase principal.

+1

Eso no es verdad. Cuando se elimina un objeto administrado, se marca para su eliminación, pero no puede liberar la memoria, ya que infringe la política de administración de memoria de Apple. –

+0

Estudio esa clase NSManagedObjectContext, encontré que cuando se llama al método deleteObject, el objeto se eliminará de las tablas uniquing. –

1

tuve un problema similar que termina en una "Detectado un intento de llamar a un símbolo en las bibliotecas del sistema que no está presente en el iPhone: _Unwind_Resume llamado desde _PFFaultHandlerLookupRow función en la imagen CoreData." mensaje de error.

Mi problema era una regla de eliminación incorrecta "en cascada" en una relación en el modelo. Con esta regla, mi objeto gestionado superior se eliminó pero aún se hace referencia en el código. Después de establecer la "regla de eliminación" en esta relación para "anular", todo funcionó según lo diseñado.

-> sin problemas de datos centrales ... ¡problema de diseño!

Johnny

Cuestiones relacionadas