2012-02-24 10 views
7

Zdobył Stumpera (przynajmniej dla mnie).Obiekt zarządzany Rdzeń Danych nie widzi powiązanych obiektów do czasu ponownego uruchomienia Symulator

Używam iOS 5.0 z/ARC, a Core Data wewnątrz UIManagedDocument.

Posiadam Entity (Group) ze związkiem to-many (zwane osobami) do entity (Person). Gdy dodaję nową grupę i dodaję nową osobę (ustawiającą relację grupy .group do nowej grupy), nie mogę odzyskać powiązanych osób, używając predykatu w jednostce Osoba, gdzie ("grupa ==% @", myGroup). Próbowałem również użyć setera addPerson grupy.

Po wyłączeniu symulatora XCode i ponownym uruchomieniu go, rozpoznaje relację, która została utworzona w poprzednim przebiegu, mogę nawet dodawać nowe osoby do istniejącego obiektu grupy. Nie mogę dodać nowej grupy, a następnie dodawać osoby bez wyłączania symulatora (lub urządzenia, jeśli używam urządzenia), aby zobaczyć relację.

Jeśli zrobię [liczba osób w grupie], natychmiast po dodaniu nowej grupy i powiązanej osoby, poda mi poprawną liczbę. Ale pobieranie z predykatem nie działa, dopóki nie uruchomię ponownie aplikacji.

Wygląda na to, że obiekt managedObjectContext obiektu UIManagedDocument nie widzi relacji. Próbowałem zapisać kontekst, zapisując context.parentContext i zapisując dokument. Nic z tego nie pomogło.

Wszelkie pomysły będą mile widziane!

+0

Czy ustawiłeś odwrotną relację w swoim modelu? – Rog

+0

Tak. Mam jeden do wielu z grupy do osoby, nazwanych ludzi. I odwrotnie jeden do jednego od osoby do grupy, nazwanej grupy. – Byron

Odpowiedz

10

UIManagedDocument zapisze, cóż, w zasadzie, kiedy to się spodoba; nie masz kontroli, kiedy to nastąpi. Z pewnością jednak zaoszczędzi to na zakończeniu aplikacji, dlatego po ponownym uruchomieniu zobaczysz wstawki.

W rezultacie, chociaż możesz myśleć, że masz stałe identyfikatory obiektów, w rzeczywistości są one tymczasowe i dlatego nie można ich pobrać. Po prostu wyrzucenie ich przez NSLog sprawdzi to, ponieważ tymczasowe identyfikatory obiektów pojawią się jako takie po zalogowaniu.

Aby wymusić ich trwałość, a tym samym ich użycie, po wykonaniu dodatków spróbuj wykonać następujące czynności. Zakładając, że masz UIManagedDocument jako ivar:

- (void)performUpdate 
{ 
    NSManagedObjectContext * context = self.managedDocument.managedObjectContext; 
    NSSet     * inserts = [context insertedObjects]; 

    if ([inserts count]) 
    { 
     NSError * error = nil; 

     if ([context obtainPermanentIDsForObjects:[inserts allObjects] 
              error:&error] == NO) 
     { 
      NSLog(@"BAM! %@", error); 
     } 
    } 

    [self.managedDocument updateChangeCount:UIDocumentChangeDone]; 
} 

Oczywiście, można by wymienić obsługi błędów z czymś nieco lepszym tutaj. UIManagedDocument zostanie teraz zapisany w pewnym momencie w przyszłości (ponownie, nie masz absolutnej kontroli nad tym, kiedy to się stanie, po prostu prosimy, aby zrobił to w ostatnim wierszu, w taki sam sposób, w jaki zrobiłby to menedżer cofania) , ale nowo wstawione obiekty powinny mieć teraz użyteczne stałe identyfikatory, a pobory powinny działać poprawnie.

I tak, wydaje mi się to trochę dziwne, ale wydaje się, że jest to właściwy sposób robienia rzeczy za pomocą UIManagedDocument w grze.

Szczerze mówiąc, chciałbym, aby ktoś powiedział mi, że jestem niepoprawny i zapewni lepsze rozwiązanie.

+0

Allan, DZIĘKUJĘ !!!Kosztowało mnie to wiele godzin lub wirowanie kół. Jak powiedziałeś, nie jest to "wymagany" krok od wszystkich tutoriali i instrukcji, które przeczytałem, ale to sprawia, że ​​moja aplikacja działa poprawnie. – Byron

+0

Jeśli ktoś ma pojęcie, w jaki sposób możemy zapobiec konieczności używania tego, chętnie bym go usłyszał. – Byron

+0

Wydaje mi się, że jest dość oczywiste, że nie ma jeszcze żadnego przykładowego kodu dostarczonego przez firmę Apple dla UIManagedDocument. Myślę, że może to być niezamierzony błąd wprowadzony w wyniku nowych zagnieżdżonych kontekstów obiektów zarządzanych i czekają na naprawę przed dostarczeniem przykładowego kodu. Teoria jednego frajera. –

-1

Miałem podobny problem, aktualizacja wykonania nie pomogła mi. Zrobiło to:

NSArray *insertedObjs = [[self.managedObjectContext insertedObjects] allObjects]; 
if ([insertedObjs count] > 0) { 
    NSError * error; 
    [self.managedObjectContext obtainPermanentIDsForObjects:insertedObjs error:&error]; 
} 

Uruchomię to po włożeniu obiektów i przed zapisaniem.

Powiązane problemy