2011-08-10 4 views
5

Występuje ten problem, gdy różne wątki wyświetlają różne dane w tych samych rekordach, ale w różnych kontekstach zarządzanego obiektu (moc). Nasza aplikacja synchronizuje się w tle z interfejsem API serwera. Cała synchronizacja odbywa się na własnej ścieżce i przy użyciu własnej mocy. Odkryliśmy jednak, że gdy dane zostaną zaktualizowane na głównym moc, że zmiana danych nie jest wyświetlana w tle moc. Jakieś pomysły, co może się wydarzyć? Oto kilka szczegółów: używamy Grand Central Dispatch, tak jak w przypadku operacji synchronizacji na swoim wątku: Sprawdziliśmy, które rzeczy w kolejce są uruchomione i wszystko dzieje się w oczekiwanej kolejce.Aktualizacje ios coredata nie są widoczne w różnych kontekstach obiektów zarządzanych - dane różnią się między kontekstami

- (void) executeSync; { 

    dispatch_async(backgroundQueue, ^(void) { 
     if([self isDebug]) 
      NSLog(@"ICSyncController: executeSync queue:%@ \n\n\n\n\n", [self queue]); 


     for(id <ICSyncControllerDelegate> delegate in delegates){ 
      [delegate syncController:self]; 
     } 
     if([ICAccountController sharedInstance].isLoggedIn == YES && shouldBeSyncing == YES) { 
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 300ull * NSEC_PER_SEC), dispatch_get_current_queue(), ^{ 
       [self executeSync]; 
      }); 
     } 

    }); 
} 

Oto jak tworzymy tło w tle i potwierdziliśmy, że został stworzony w tle kolejki.

Powinienem dodać, że nasze tło mocy wymaga danych, a te rekordy zwrócone z tej akcji nadal mają stare wartości dla niektórych pól. W jaki sposób moc tła pobiera aktualne dane, które zostały już zapisane przez główny moc? Myślałem, że po prostu prosząc, otrzymam obecny stan tych zapisów ..

przez ponaglenie mam na myśli następujące: Tło MOC wykonuje kolejne "zapytanie", aby uzyskać "świeże" dane po zmianie rekordów przez główny moc, ale dane mają stare wartości - a nie zaktualizowane wartości widoczne w głównym moc.

+ (NSArray *)dirtyObjectsInContext:(NSManagedObjectContext *)moc { 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(memberships, $m, $m.category.name == %@ AND $m.syncStatus > %d)[email protected] > 0", MANAGED_CATEGORY_FAVORITES, ManagedObjectSynced]; 

    return [self managedObjectsWithPredicate:predicate inContext:moc]; 
} 

Twoja pomoc jest niezwykle ceniona jak już próbuje dowiedzieć się tego, czy znajduje się obejść ten nie obejmuje wodowania nasze wątki na dni.

Odpowiedz

4

Tak to powinno działać - istotną rolą kontekstu obiektów zarządzanych jest ochrona przed zmianami danych w innych wątkach. Wyobraź sobie spustoszenie, które mogłoby powstać, gdybyś miał wątek tła modyfikujący te same obiekty, których używał główny wątek bez jakiegoś schematu synchronizacji.

Przeczytaj Communicating Changes Between Contexts, aby dowiedzieć się, jak scalać zmiany z jednego kontekstu do drugiego.

+1

Dzięki za pomoc. Sądzę, że zaskoczyło mnie to, że rekwirujemy rekordy, ale nie otrzymujemy aktualnych danych. Właśnie odkryliśmy, że robi to [[[ICCoreDataController sharedInstance] backgroundObjectContext] reset]; na tle kontekstu rozwiązały nasze problemy. Wciąż jednak chciałbym to lepiej zrozumieć. Dzięki!! –

4

używam następujący kod do nasłuchiwania zmian w kontekście 2, tak że kontekst 1 utrzymuje się do chwili obecnej:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc addObserver:context1 
     selector:@selector(contextTwoUpdated:) 
      name:NSManagedObjectContextDidSaveNotification 
      object:context2]; 

to powoduje ten sposób nazywać kontekstu 1, i wywołać metodę scalania :

- (void)contextTwoUpdated:(NSNotification *)notification { 
    [context1 mergeChangesFromContextDidSaveNotification:notification]; 
} 

efektem ubocznym jest to każda NSFetchedResultsController, który jest dołączony do context1 wyśle ​​różnorodne wiadomości do swojego delegata informując go o zmianach,

Nigdy nie próbowałem odsłuchiwać obu sposobów, podczas gdy użytkownik zmienia obiekt i aktualizuje go na komputerze od tyłu - podejrzewam, że być może będziesz musiał zarządzać scaleniami, jeśli tak jest, ponieważ jest on jednokierunkowy (i oparty na wszystkich użytkownikach). ja zakładam, że wszystkie aktualizacje są ważne