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
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:
- użyj jednego
NSPersistentStoreCoordinator
Na program. Nie potrzebujesz ich na wątek. - Utwórz jeden
NSManagedObjectContext
na każdy wątek. - nigdy nie przekazuj
NSManagedObject
na wątku do drugiego wątku. - zamiast tego pobieramy identyfikatory obiektów przez
-objectID
i przekazujemy je do innego wątku.
Więcej Zasady:
- 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.
- i uważaj na zasady scalania, jeśli wprowadzasz zmiany w zarządzanych obiektach z więcej niż jednego wątku.
-
NSManagedObjectContext
' s-mergeChangesFromContextDidSaveNotification:
jest pomocna.
Ale powtórzę, proszę uważnie przeczytać dokument! Naprawdę warto!
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 ...>
}
}];
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.
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