2013-04-12 14 views
6

Spędziłem już kilka godzin nad tym i nie mogę znaleźć rozwiązania. Po pierwsze, niektóre specyfikacje, co mam:Niezgodność z Core Data - pobieranie czasami nic nie zwraca

  • Objective C-iOS 6 app z rdzeniem dane Dane
  • Core jest inicjowany z UIManagedDocument, który posiada auto oszczędzania włączona
  • ManagedContext z UIManagedDocument jest przechowywany w zmiennej statycznej i ponownie użyte w aplikacji
  • Aplikacja korzysta z pakietu RestKit, a ja korzystam z kategorii ActiveRecord, którą zapewnia.

Mam model z jednostką Team. W aplikacji znajduje się kontroler widoku Lista zespołów, który ładuje zespoły z zaplecza. Backend zwraca tablicę JSON, zawierającą między innymi identyfikator zespołu. Przechowuję ten identyfikator w polu "id" w moim modelu i podczas iteracji po odpowiedzi serwera, sprawdzam, czy zespół dla danego ID już istnieje. Jeśli tak, aktualizuję tylko jego informacje i przekazuję obiekt dalej, jeśli nie - najpierw go tworzę.

I tu następuje dziwaczność. Działa to 90% czasu. Mogę załadować kontroler listy zespołów, przejść dalej w aplikacji, wrócić do kontrolera (który ponownie ładuje dane) i wszystko jest w porządku przez większość czasu. Jednak od pewnego czasu moje żądanie pobierania niczego nie zwróci. Tak jak w:

NSArray *results = [context executeFetchRequest:request error:&error]; 

zwróci pustą tablicę, a błąd jest również pusty. Nic na serwerze nie ulega zmianie. Żądanie, gdy próbuję go debugować, wygląda następująco:

<NSFetchRequest: 0x127a0e20> (entity: Team; predicate: (id == "123"); sortDescriptors: ((null)); limit: 1; type: NSManagedObjectResultType;) 

Kiedy podgląd sklep sqlite w zewnętrznej aplikacji, widzę, że pozycja zespołu w tym ID jest obecny, aw pozostałych 90% czasy, kiedy rzeczywiście zostanie załadowany. Co jeszcze bardziej dziwaczne, kiedy już okazało SQLDebug na widzę:

2013-04-12 12:00:27.934 SportLink[10831:c07] CoreData: annotation: fetch using 
NSSQLiteStatement <0x12656d10> on entity 'Team' with sql text 'SELECT 0, t0.Z_PK, 
t0.Z_OPT, t0.ZACI1, t0.ZACI2, t0.ZACI3, t0.ZALTFIRSTNAME, t0.ZALTSECONDNAME, t0.ZCOLOR1, 
t0.ZCOLOR2, t0.ZGENDER, t0.ZICON, t0.ZID, t0.ZLOCATION, t0.ZLOGO1, t0.ZLOGO2, t0.ZNAME, 
t0.ZTYPE, t0.ZSPORT FROM ZTEAM t0 WHERE t0.ZID = ? LIMIT 133' returned 6 rows 

co oznacza, że ​​sklep podkład faktycznie pobrane dane, ale z jakiegoś powodu nie przekazywać go dalej. Teraz:

  • Robię wszystko, co w głównym wątku, więc nie jest to problem
  • wierzę, że automatycznego zapisywania nie jest także problemem, ponieważ może się zdarzyć, nawet kiedy zamknąć aplikację i otwórz go ponownie z danymi już obecnymi.

Jakieś pomysły na to, co tu się dzieje?

Edytuj: Profilowałem aplikację za pomocą instrumentów. Właśnie wszedłem do problematycznego VC, potem wszedłem do jego kontrolera i zostawiłem, powtórzyłem to kilka razy, aż problem zaczął się zamanifestować. Oto wyniki. Może łatwiej będzie wiedzieć, co się dzieje tutaj:

Instruments output

+0

Kiedy wystrzeliwujesz żądanie w swoim 'TeamListVC'? Co robisz po załadowaniu wyników? Możesz dodatkowo zalogować się "[liczba wyników]" po Twojej prośbie, by trochę prześledzić. – flashfabrixx

+0

spróbuj ustawić sticheInterval głównego kontekstu na 0 –

+0

@DanShelly niestety to nie pomogło. – mav

Odpowiedz

5

Po kilku dniach dochodzenia, w końcu znalazłem przyczynę tego błędu. Kod, który był pobierania podmiot zespołu wyglądał następująco:

Team *team = [Team findFirstByAttribute:WSK_ID withValue:data[WSK_ID] inContext:moc]; 

WSK_ID jest tylko określenie dla @"id".data to słownik, który otrzymałem od RestKit, z odpowiedzi JSON. Ponieważ nie był rzutowany na dowolny typ, prawdopodobnie był to NSString, podczas gdy właściwość jednostki Teamu oczekiwała NSNumber. Chociaż nie wiem, co czasami zawodziło, zmieniając ten bit na:

Team *team = [Team findFirstByAttribute:WSK_ID withValue:@([data[WSK_ID] intValue]) inContext:moc]; 

tj. przerzucenie ciągu ID na int, a następnie zaznaczenie go NSNumber rozwiązało problem.

+0

Sqlite3 na iOS jest absolutnie straszny, jeśli chodzi o współdziałanie, konwersję typu itp. - niezależnie od tego, czy używasz CoreData. Z mojego doświadczenia wynika, że ​​chociaż CoreData jest pomocna w prostych scenariuszach, to dodatkowo zwiększa złożoność przez ukrywanie pewnych danych. – Brandon

Powiązane problemy