Core Data multi thread application

Próbuję używać podstawowych danych w sposób wielowątkowy. Po prostu chcę pokazać aplikację z wcześniej pobranymi danymi podczas pobierania nowych danych w tle. Powinno to umożliwić użytkownikowi dostęp do aplikacji podczas procesu aktualizacji.

Mam NSURLConnection, które pobierają plik asynchronicznie używając delegata( i pokazując postęp), a następnie używam Xmlparsera do parsowania nowych danych i tworzenia nowych NSManagedObjects w osobnym kontekście, z własnym persistentStore i za pomocą osobnego wątku.

Problem polega na tym, że tworzenie nowych obiektów w tym samym kontekście starego, podczas pokazywania go, może spowodować wyrzucenie wyjątku BAD_INSTRUCTION. Postanowiłem więc użyć osobnego kontekstu dla nowych danych, ale nie mogę znaleźć sposobu, aby przenieść wszystkie obiekty do innego kontekstu po zakończeniu.

Paolo aka SlowTree

Author: JosephH, 2010-01-26

3 answers

Zacznij od współbieżności Apple z dokumentacją Core Data . Przeczytaj to bardzo uważnie... Wiele razy byłem ugryziony przez moje nieporozumienia!

Podstawowe zasady to:

  1. użyj jednego NSPersistentStoreCoordinator Na program. Nie potrzebujesz ich na wątek.
  2. Utwórz jeden NSManagedObjectContext na każdy wątek.
  3. nigdy nie przekazuj NSManagedObject na wątku do drugiego wątku.
  4. zamiast tego pobieramy identyfikatory obiektów przez -objectID i przekazujemy je do innego wątku.

Więcej Zasady:

  1. upewnij się, że zapisałeś obiekt w sklepie przed uzyskaniem ID obiektu. Do momentu zapisania są tymczasowe i nie można uzyskać do nich dostępu z innego wątku.
  2. i uważaj na zasady scalania, jeśli wprowadzasz zmiany w zarządzanych obiektach z więcej niż jednego wątku.
  3. NSManagedObjectContext ' s -mergeChangesFromContextDidSaveNotification: jest pomocna.

Ale powtórzę, proszę uważnie przeczytać dokument! Naprawdę warto!

 144
Author: Yuji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 13:43:49

Obecnie[Maj 2015] współbieżność Apple z dokumentacją Core Data jest w najlepszym razie bardzo myląca, ponieważ nie obejmuje żadnych ulepszeń w iOS 5, a tym samym nie pokazuje już najlepszych sposobów na jednoczesne korzystanie z core data. Istnieją dwie bardzo ważne zmiany w systemie iOS 5 - konteksty nadrzędne i nowe typy współbieżności/wątków.

Nie znalazłem jeszcze żadnej pisemnej dokumentacji, która kompleksowo obejmuje te nowe funkcje, ale WWDC 2012 wideo " sesja 214-Core Data Best Practices" wyjaśnia to wszystko bardzo dobrze.

Magical Record wykorzystuje te nowe funkcje i może warto zajrzeć.

Prawdziwe podstawy są nadal takie same - nadal można używać tylko obiektów zarządzanych, w których wątek został utworzony.

Możesz teraz użyć [moc performBlock:], aby uruchomić kod w odpowiednim wątku.

Nie ma potrzeby używania mergechangesfromcontextdidsavenotification: anymore; zamiast tego utwórz kontekst potomny, aby zmiany, a następnie zapisz kontekst potomny. Zapisanie kontekstu potomnego spowoduje automatyczne przesunięcie zmian do kontekstu nadrzędnego, a aby zapisać zmiany na dysku, wystarczy wykonać zapis w kontekście nadrzędnym w jego wątku.

Aby to zadziałało, musisz utworzyć kontekst nadrzędny z typem współbieżnym, np:

mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

Następnie w wątku tła:

context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setParentContext:mainManagedObjectContext];

<... perform actions on context ...>

NSError *error;
if (![context save:&error])
{
    <... handle error ...>
}
[mainManagedObjectContext performBlock:^{
    NSError *e = nil;
    if (![mainContext save:&e])
    {
        <... handle error ...>
    }
}];
 75
Author: JosephH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-10 19:40:33

Mam nadzieję, że pomoże to wszystkim ludziom, którzy napotykają problemy z wykorzystaniem podstawowych danych w środowisku wielowątkowym.

Spójrz na "Top Songs 2" w dokumentacji apple. Za pomocą tego kodu wziąłem "czerwoną pigułkę" Matrixa i odkryłem nowy świat, bez podwójnego wolnego błędu i bez błędów. : D

Mam nadzieję, że to pomoże.

Paolo

P. s. Wielkie dzięki Yuji, w opisanej powyżej dokumentacji znalazłem ten przykład.

 2
Author: SlowTree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-09 12:16:47