5

Mam dwie instancje NSManagedObjectContext: jedna jest używana w głównym wątku, a druga jest używana w wątku tła (przez NSOperation.) W przypadku bezpieczeństwa wątków, te dwa konteksty mają tylko NSPersistentStoreCoordinator.Kopiowanie oczekujących zmian między NSManagedObjectContexts z udostępnionym magazynem trwałym?

Problem polegający na tym, że oczekujące zmiany w pierwszym kontekście (w wątku głównym) nie są dostępne dla drugiego kontekstu, dopóki nie zostanie przeprowadzona -save. Jest to zrozumiałe, ponieważ współużytkowany magazyn trwały nie będzie miał kopii plików NSManagedObjects śledzonych przez -insertedObjects, -updatedObjects i .

Niestety, stanowi to problem z doświadczeniem użytkownika: wszelkie niezapisane zmiany nie pojawią się w (czasochłonnych) raportach wygenerowanych w wątku tła.

Jedyne rozwiązanie, jakie mogę sobie wyobrazić, to paskudne: weź wstawione, zaktualizowane i usunięte obiekty z pierwszego kontekstu i przeszczep je na wykres obiektu drugiego kontekstu. W zbiorze danych są dość złożone relacje, więc nie chcę iść w tym kierunku. Mam nadzieję, że ktoś tutaj będzie lepszym rozwiązaniem.

Odpowiedz

4

Jeśli jest to poniżej 10.7, są pewne rozwiązania: jeden z nich można zagnieździć ManagedObjectContexts, więc można "zapisać" w tym, który jest modyfikowany i nie będzie zapisać aż do dysku, ale będzie zmiany dostępne dla innych dzieci kontekstu głównego.

Przed 10,7 prawdopodobnie będziesz musiał skopiować zmiany na siebie. Nie jest to super-trudne, ponieważ wystarczy jeden obiekt, który nasłuchuje pod kątem NSManagedObjectContextObjectsDidChangeNotification, a następnie po prostu ponownie zastosować zmiany dokładnie z głównego kontekstu. (Powinno być około 20 linii kodu.) Nigdy nie musisz zapisywać tego drugiego kontekstu, jak zakładam?

+0

Dzięki Wil! Chciałbym skierować 10.6, choć robi się to coraz trudniej każdego dnia :-) - Śledzę już powiadomienie o zmianie, ale nie jestem pewien, jak ponownie zastosować zmiany i zachować relacje encji. Czy możesz być trochę bardziej konkretny? – chockenberry

+0

Ah tak. W niewidzialny sposób opierałem się na moim modelu, który polega na tym, że każdy obiekt ma klucz UUID (ciąg znaków), który sam utrzymywałeś. –

+0

Bez zapisania w tle MOC wstawki nie będą widoczne dla głównego MOC (bez zagnieżdżonych MOC). Aktualizacje/usunięcia dla istniejących obiektów powinny działać, jeśli wysłuchasz powiadomienia o zmianie (wydanego po processPendingChanges) i zaktualizujesz obiekty samodzielnie. – diederikh

2

Nie jesteś pewien, czy masz jakieś ograniczenia systemu operacyjnego, ale w systemie iOS 5/Mac OS 10.7 możesz użyć zagnieżdżonych kontekstów obiektów zarządzanych, aby to osiągnąć. Wierzę, że kontekst podrzędny jest w stanie pobrać niezapisane zmiany w rodzicu, po prostu wykonując nowe pobranie.

Edit: Wygląda Wil pokazał mi to, ale tak, przed iOS 5/Mac OS 10.7 musisz nasłuchiwać NSManagedObjectContextDidSaveNotification i przyjrzeć słownika userinfo dla dodana/zaktualizowana/usunięta obiekty.

0

Alternatywne rozwiązanie może wymagać użycia pojedynczego kontekstu obiektu zarządzanego i zapewnienia własnego bezpieczeństwa wątków w zakresie dostępu do niego lub użycia kontekstowych metod blokowania i odblokowywania.

0

Próbowałbym uczynić główny wątek normalnym zapisem, aby drugi kontekst mógł po prostu scalić zmiany z jego kontekstem. "walka" z zamierzonym interfejsem API nigdy nie jest dobrym pomysłem. Można oznaczyć nowo zapisany rekord atrybutem pośrednim i usunąć później, jeśli użytkownik w końcu anuluje edycję.

Rozwiązywanie problemów z tych atrybutów w swoich jednostkach i zapytań w wątku tła z dopasowywania opiera byłoby proste ...

I to byłoby stabilne rozwiązanie, jak również. Pochodzę ze świata opartego na bazie danych (oracle), z którego często korzystamy z takich wzorców (atrybuty statusu w rekordach), aby dane były widoczne/niewidoczne dla innych sesji DB (co równa się wątkom w aplikacji kakao). Działa zawsze bez problemów. Inne wątki/sesje zawsze wyświetlają tylko zmiany, które działają w większości RDBMS.

Powiązane problemy