2010-09-12 17 views
6

Okazjonalne czytelnik i pierwszy raz Pytający pytanie, więc proszę być łagodne :)Nieprawidłowy błąd danych rdzenia spowodowany nadmiernym zwolnieniem?

Tworzę zarządzanego obiektu (rachunku), które jest przekazywane do kontrolera widoku gdzie jego dziecko jest ustawiony w nieruchomości, która jest zatrzymany.

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

Widok Controller Interface:

@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 

więc w przykładowym kodzie 1 Mam zwolniony obiekt konta, bo nie interesuje mnie w tej metodzie. Ponieważ jest on przechowywany przez AddAccountViewController Mam wpis w 'AddAccountViewController' s dealloc, który go zwalnia.

Jednak kiedy idę, aby usunąć obiekt z ManagedObjectContext Aplikacja ulega awarii z następującym (raczej niejasny) Błąd:

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. 

Po wielu debugowania & ciągnięcie za włosy odkryłem, że jeśli ja nie Uwolnij konto w metodzie AddAccountViewController 's dealloc metoda działa poprawnie i nie wydaje się przeciekać zgodnie z Instruments.

Czy ktoś może rzucić światło na to, co się dzieje? Rozumiem z dokumentów o właściwościach, które zatrzymane muszą zostać zwolnione. Co przeoczyłem?

Aktualizacja odpowiedzieć na pytanie Kevina

kod, aby usunąć obiekt z ManagedObjectContext jest w RootViewController (czyli posiadających kontroler dziecko)

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

Czy można wyświetlić kod, który usuwa go z NSManagedObjectContext? I dzieje się to wewnątrz AddAccountViewController lub gdzie indziej? –

+0

'childController.anAccount = account;' ta linia NIE zachowuje 'konta'. Kopiuje go do "konta ana". To w ogóle nie daje +1, a będziesz musiał zwolnić 'anAccount' w metodzie dealloc AddAccountViewcontroller. –

+0

@Thomas: '@property (nonatomic, retain) Konto * anAccount;' Dlaczego by nie zachował? – Pyetras

Odpowiedz

1

Po pierwsze: To brzmi jak błąd ze strony Apple. Core Data wywołuje _Unwind_Resume, co jest (prawdopodobnie) rodzajem wyjątku odwijania. W telefonie istnieje wyjątek - rozwijanie, ale (jak sądzę) używa ARM ABI, który używa nazw funkcji zaczynających się od __cxa_. Czy korzystasz z symulatora? Która wersja pakietu SDK?

Może być dodatkowe wydanie pływające w dowolnym miejscu, które jest "zrównoważone" po usunięciu połączenia z numerem [account release];.

"Instrumenty nie wykazują żadnych wycieków" nie oznacza, że ​​nie ma żadnych; na koniec sprawdziłem, że się pomyliłem przez cykle (to znaczy, nie pokazałoby przecieku, gdybyś zapomniał usunąć IBOutlety w dealloc). Testowałem z NSMutableData * d = [NSMutableData dataWithLength:1<<20]; memcpy(d.mutableBytes, &d, 4);, ale łatwiejszy test to tylko [[UIView alloc] initWithFrame:CGRectZero].

Jeśli uważasz, że jest to problem związany z zachowaniem/zwolnieniem, raz je usunąłem, przesyłając polecenie keep/release/autorelease, aby zadzwonić do NSLog. Następnie dodałem punkty przerwania na wszystkich z nich, ustawiłem je tak, aby uruchamiały polecenie "bt", i kliknąłem na autokontynę. Następnie uruchom urządzenie, które się zepsuło (w moim przypadku uważam, że było to tylko dodatkowe zabezpieczenie), wydrukuj dane wyjściowe dziennika, przyklej je na tablicy i zatrzymaj na pół godziny, zachowując zgodność i zwolnienia.

+1

Rzeczywiście usunięcie '[account release];' na końcu pierwszego bloku oznacza, że ​​'keep '&' release' w 'AddAccountViewController' są poprawnie wyważone, a aplikacja nie ulega awarii po zapisaniu po usunięciu wpisu z' ' ManagedObjectContext'. Odnośnie pierwszej części, uruchomiłem kod na symulatorze i urządzeniu i otrzymałem ten błąd. SDK był 4,1GM. – tarasis

+0

Jeśli usunięcie '[account release];' jak opisano to rozwiązuje, to AddAccountViewController jest uszkodzony (w odniesieniu do konwencji zarządzania pamięcią Obj-C). Nie jest łatwo ustalić, gdzie jest on uszkodzony, bez patrzenia na cały kod wewnątrz AddAccountViewController, który dotyka właściwości anAccount lub jej instancji kopii zapasowej. (Dodatkowo, właściwości prefiksów/ivars z "a" lub "an" nie są znane w jakiejkolwiek konwencji kodowania i są sprzeczne z miejscami, w których używa ich Apple.) –

0

Kiedy usuniesz dowolny obiekt zarządzany, system automatycznie zwolni wszystkie odniesienia związane z tym obiektem. Nie ma zatem potrzeby programowego odpierania obiektów. Po usunięciu obiektu nie można uzyskać dostępu do tego obiektu w klasie nadrzędnej.

+1

To nieprawda. Po usunięciu obiektu zarządzanego jest on oznaczony do usunięcia, ale nie może zwolnić pamięci, ponieważ narusza zasady zarządzania pamięcią w jabłkach. –

+0

Studiuję klasę NSManagedObjectContext, stwierdziłem, że gdy zostanie wywołana metoda deleteObject, obiekt zostanie usunięty z tabel unikowych. –

1

miałem podobny problem kończącą w „Wykryto próbę zadzwonić symbol w bibliotekach systemu, który nie jest obecny na iPhone: _Unwind_Resume wywoływana z funkcji _PFFaultHandlerLookupRow Image CoreData”. komunikat o błędzie.

Moim problemem była zła "kaskadowa" reguła usuwania relacji w modelu. Z tą regułą mój najwyższy zarządzany obiekt został usunięty, ale nadal jest przywoływany w kodzie. Po ustawieniu "reguły usuwania" w tej relacji na "nulify" wszystko działało zgodnie z założeniami.

-> brak problemu z danymi podstawowymi ... problem projektowy!

Johnny

Powiązane problemy