2010-09-12 18 views
6

lettore occasionale e prima domanda richiedente volta, quindi si prega di essere gentile :)Odd Core Errore nei dati causato da un eccessivo rilascio?

sto creando un Managed Object (account), che si passa in un controller di vista del bambino, dove la sua soggiornare in una proprietà che è mantenuto.

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 interfaccia controller:

@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 

Così nel codice di esempio 1 Ho rilasciato l'oggetto account, perché io non sono più interessati a questo sono in questo metodo. Come è mantenuto dal AddAccountViewController Ho una voce in AddAccountViewController 's dealloc che lo rilascia.

Tuttavia quando vado per eliminare l'oggetto dal ManagedObjectContext l'applicazione si blocca con il seguente (poco chiaro) di errore:

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. 

Dopo molte debug & tirare i capelli ho scoperto che se non lo faccio release account in AddAccountViewController 's dealloc metodo l'app funziona in modo corretto e non sembra perdere secondo gli strumenti.

Qualcuno può fare luce su cosa sta succedendo? Capisco dai documenti sulle proprietà che quelli ritenuti devono essere rilasciati. Cosa mi sono perso?

Update per rispondere alla domanda di Kevin

Il codice per eliminare l'oggetto dal ManagedObjectContext è nel RootViewController (che tiene il controller bambino)

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

Potete mostrare il codice che lo elimina dalla NSManagedObjectContext? E questo accade all'interno di AddAccountViewController o altrove? –

+0

'childController.anAccount = account;' questa riga NON conserva 'account'. Lo copia su 'anAccount'. Questo non fa +1 sul suo mantenimento, e dovrai solo rilasciare 'anAccount' nel metodo dealloc di' AddAccountViewcontroller'. –

+0

@Thomas: '@property (nonatomic, retain) Account * anAccount;' Perché non dovrebbe conservarlo? – Pyetras

risposta

1

In primo luogo: Suona come un insetto da parte di Apple. Core Data chiama lo _Unwind_Resume, che è (probabilmente) una sorta di eccezione per lo svolgimento. Esistono eccezioni nel telefono, ma (penso) utilizza l'ABI ARM, che utilizza nomi di funzioni che iniziano con __cxa_. Stai correndo sul simulatore? Quale versione dell'SDK?

Potrebbe esserci un rilascio extra in giro da qualche parte che è "bilanciato" quando si rimuove la chiamata a [account release];.

"Gli strumenti non mostrano alcuna perdita" non significa che non ce ne sono; l'ultima volta che ho controllato è confusa dai cicli (cioè non mostrava una perdita se ti sei dimenticato di disinserire gli IBOutlet in dealloc). Ho provato con NSMutableData * d = [NSMutableData dataWithLength:1<<20]; memcpy(d.mutableBytes, &d, 4);, ma un test più semplice è solo [[UIView alloc] initWithFrame:CGRectZero].

Se si ritiene che si tratti di un problema di mantenimento/rilascio, una volta ho eseguito il debug di questi eseguendo l'override di retain/release/autorelease per chiamare NSLog. Ho quindi aggiunto i punti di interruzione su tutti loro, li ho impostati per eseguire il comando "bt" e ho fatto clic su autocontinue. Quindi esegui la cosa che si interrompe (nel mio caso penso che sia stata solo una riserva in più), stampa l'output del registro, incollalo su una lavagna e trascorri mezz'ora corrispondenti a ritardi e rilasci.

+1

Infatti rimuovere la '[versione account];' alla fine del primo blocco significa che il 'retain' e' release' in 'AddAccountViewController' sono correttamente bilanciati e l'app non si blocca quando si salva dopo aver rimosso una voce dal' ManagedObjectContext'. Per quanto riguarda la prima parte, eseguivo il codice sia sul simulatore che sul dispositivo e ottenevo quell'errore. L'SDK era 4.1GM. – tarasis

+0

Se la rimozione di '[account release];' come descritto lo corregge, allora AddAccountViewController è danneggiato (rispetto alle convenzioni di gestione della memoria Obj-C). Non è facile capire dove si è rotto senza guardare tutto il codice all'interno di AddAccountViewController che tocca la proprietà anAccount o la sua variabile di istanza di backup. (Inoltre, il prefisso di proprietà/ivars con "a" o "an" non è in alcuna convenzione di codifica che conosco e contraddice i luoghi in cui Apple lo utilizza.) –

0

Quando si elimina un oggetto gestito, il sistema rilascia automaticamente tutti i riferimenti relativi a tale oggetto. Quindi non c'è bisogno di realese oggetto programmaticamente. Una volta eliminato l'oggetto, non è possibile accedere a quell'oggetto nella classe genitore.

+1

Non è vero. Quando un oggetto gestito viene eliminato, viene contrassegnato per l'eliminazione ma non può rilasciare la memoria poiché viola i criteri di gestione della memoria delle mele. –

+0

Studio questa classe NSManagedObjectContext, ho scoperto che quando viene chiamato il metodo deleteObject, l'oggetto verrà rimosso dalle tabelle uniquing. –

1

ho avuto un problema simile che termina in una "Rilevato un tentativo di chiamare un simbolo in librerie di sistema che non è presente su iPhone: _Unwind_Resume chiamato dalla funzione _PFFaultHandlerLookupRow nell'immagine CoreData." messaggio di errore.

Il mio problema era una regola di cancellazione "a catena" errata su una relazione nel modello. Con questa regola, il mio oggetto gestito in alto è stato eliminato ma ancora fatto riferimento nel codice. Dopo aver impostato la "regola di eliminazione" su questa relazione su "nulify", tutto ha funzionato come progettato.

-> nessun problema di dati di base ... problema di progettazione!

Johnny

Problemi correlati