2013-07-12 25 views
7

W mojej aplikacji mam możliwość wyczyszczenia wszystkich danych z bazy danych. Po zakończeniu tej operacji pakiet JSON jest następnie analizowany, a następnie zapisywany w bazie danych (w celu przywrócenia bazy danych do stanu domyślnego). Operacja do parsowania i zapisywania tego JSON-a działa dobrze w każdym przypadku, z wyjątkiem czyszczenia i odtwarzania trwałego sklepu, w którym to przypadku dostaję "NSInvalidArgumentException", powód: "Magazyn trwały obiektu nie jest osiągalny z tego koordynatora NSManagedObjectContext". Ten wyjątek jest generowany podczas próby wywołania mergeChangesFromContextDidSaveNotification w moim głównym kontekście wątku po zapisaniu w kontekście tła.Błąd danych podstawowych po odtworzeniu trwałego sklepu

Odtwarzanie magazynu odbywa się na głównym wątku, gdzie podczas analizowania i zapisywania zawsze występuje w wątku tła. Oto getter dla mojego udało kontekst obiektu w celu zapewnienia nitki solidność:

- (NSManagedObjectContext *)managedObjectContext { 

    NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; 
    NSManagedObjectContext *threadContext = threadDictionary[ckCoreDataThreadKey]; 

    if (!threadContext) { 
     threadContext = [self newManagedObjectContext]; 
     threadDictionary[ckCoreDataThreadKey] = threadContext; 
    } 

    return threadContext; 
} 

metoda newManagedObjectContext daje wszystkim nowe instancje tego samego obiektu NSPersistentStoreCoordinator.

Oto kod używany aby wyczyścić magazyn (wykonywane na głównym wątku zawsze):

[self.managedObjectContext lock]; 
[self.managedObjectContext reset]; //to drop pending changes 
             //delete the store from the current managedObjectContext 
if ([[self.managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:error]) { 
    [[NSFileManager defaultManager] removeItemAtURL:storeURL error:error]; 

    [[self.managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:error]; //recreates the persistent store 

    [self addSkipBackupAttributeToItemAtURL:storeURL]; 
} 

[self.managedObjectContext unlock]; 

Dziwne jest to, że ten sam kod działa poprawnie w innych projektach, a nie istnieją różnice inne niż zawartość danych. Każda pomoc jest bardzo cenna!

Odpowiedz

13

„trwałe sklep obiektu nie jest osiągalny z koordynatorem tego NSManagedObjectContext za

Ten komunikat oznacza, że ​​próbował użyć zarządzanego obiektu, który został załadowany z magazynu danych, które po prostu usunięte. Usunąłeś magazyn trwały z koordynatora i usunąłeś plik magazynu, ale nadal masz co najmniej jeden NSManagedObject załadowany z tego sklepu. Nie możesz już używać tych obiektów, ponieważ jeśli to zrobisz, otrzymasz ten wyjątek. Upewnij się, że pozbędziesz się wszelkich istniejących obiektów zarządzanych, zanim uzyskasz jądro na stosie danych podstawowych w swoim drugim fragmencie.

Jeśli chodzi o to, dlaczego działa to w innej aplikacji, najprawdopodobniej aplikacja nie trzyma się nieaktualnych zarządzanych obiektów.

+0

istotnie, masz rację. Różnica w tym projekcie i moich innych polega na tym, że w tej aplikacji kontroler widoku root zarządza pobranym kontrolerem wyników, który nadal trzyma obiekty po usunięciu sklepu. usuwanie i ponowne ładowanie tego kontrolera po wyczyszczeniu magazynu i teraz działa świetnie. stukrotne dzięki! –

+0

Inna możliwość uzyskania tego błędu, jeśli tymczasowy kontekst - którego rodzic jest awaryjnym kontekstem - jest w toku z żądaniem pobrania, ustawianiem wartości itp. I na końcu temporaryContext chce zapisać zmiany w rodzicu. –