8

Przeprowadzam migrację modelu CoreData między dwiema wersjami aplikacji. Przechowywałem dane binarne jako obiekty blob w poprzedniej wersji i chcę je usunąć z obiektów typu blob w celu uzyskania wydajności. Mój problem polega na tym, że podczas migracji wydaje się, że Core Data ładuje wszystko do pamięci, co prowadzi do ostrzeżenia o małej pamięci, a następnie do mojej aplikacji.Brak pamięci podczas migracji danych podstawowych

dokumentacja firmy Apple sugeruje, co następuje: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmCustomizingTheProcess.html#//apple_ref/doc/uid/TP40005510-SW9

Jednak wydaje się polegać na tym, że duże obiekty są stosowane różne odwzorowanie. W moim przypadku wszystkie obiekty są zasadniczo takie same i to samo odwzorowanie musi być zastosowane do każdego z nich. Nie widzę w tym przypadku, jak mógłbym zastosować swoją technikę.

Jak obsługiwać migrację z bardzo dużymi obiektami?

Odpowiedz

2

Zgaduję, że masz kilka zmian, które chcesz wprowadzić, oprócz wyciągania danych z obiektów typu blob. Moją sugestią jest przeprowadzenie migracji w kilku etapach. W pewnym sensie myślę głośno, więc może być możliwe poprawienie tego. Wymaga to użycia SQLite.

Aby dokonać tej pracy, będziesz mieć trzy wersje modelu:

  1. Oryginalny wzór
  2. Model z atrybutem usunięte (i ewentualnie ze szczególnym unikatowy identyfikator added-- patrz poniżej)
  3. model ze wszystkich wprowadzonych zmian, w tym dodanie nowego podmiotu i relacji zastępujących atrybut

Powodem tego jest, że tra nsition z wersji 1 do 2 powinien być wykonalny z automatyczną, lekką migracją. W takim przypadku Core Data nie musi ładować niczego do pamięci - po prostu wydaje instrukcje SQL, aby dokonać zmian bezpośrednio w bazie danych.

Zaczynasz od skonfigurowania swojego stałego koordynatora sklepu przy użyciu starej wersji modelu. Po załadowaniu danych przejrzyj wszystkie obiekty, które migrujesz, wyodrębnij atrybut binarny i jakoś go zapisz na dysku. Możesz użyć żądania pobierania z dozowaniem i regularnego opróżniania puli autoreleaseów, aby upewnić się, że nie zużywasz zbyt dużo pamięci na tymczasowe obiekty. Zapisz dane w katalogu, który otrzymasz z NSCachesDirectory. Oczywiście będziesz chciał przechowywać dane w sposób, który pozwoli ci powiązać je z obiektem managedObjectID obiektu.

Następnie zamknęło wszystko i poprosiło Core Data o przeniesienie sklepu z wersji 1 do wersji 2. Szczegółowe informacje można znaleźć w sekcji this link. Otwórz sklep z wersją 2.

Być może będziesz musiał dodać krok, w którym przypiszesz jakiś unikalny identyfikator do każdego obiektu, ponieważ nie jestem pewien, czy Core Data zachowuje identyfikatory obiektu, gdy robi to nie-lekki migracja. Jeśli musisz to zrobić, twój model w wersji 2 doda nowy atrybut do obiektu, z którego pobierasz dane binarne, który byłby opcjonalny lub miałby ustawioną wartość domyślną. Ponieważ niewielka migracja nie powinna zmieniać identyfikatorów managedObjectID, można zapisać mapowanie nowego unikalnego identyfikatora do zapisanych identyfikatorów managedObjectID wraz z danymi binarnymi dwa akapity temu.

Zapisz dane i zamknij magazyn.

Otwórz sklep i wykonaj migrację z wersji 2 do wersji 3, która powinna być w zasadzie kodem, który już napisałeś przed wysłaniem pytania. Po otwarciu sklepu dodaj wszystkie obiekty zapisane w sklepie w wersji 1 i skonfiguruj relacje, korzystając z danych zapisanych po drodze.

Proste, prawda?

+0

Dzięki Jacques, faktycznie to dało mi dobrą podpowiedź i zrobiłem coś podobnego bez schodzenia tak niskiego jak SQLite. Ale tworzę dwa różne sklepy i tworzę obiekty w każdym z nich. Trudnym zadaniem jest upewnienie się, że Core Data zamienia obiekty w błąd, gdy tylko zostaną użyte. – Kamchatka

Powiązane problemy