10

Piszę swoją pierwszą kompleksową aplikację przy użyciu Core Data i chcę zobaczyć, jaki jest najlepszy sposób śledzenia zmian/aktualizacji/usuwania obiektów. Mam na przykład encję Notes i encję Lokalizacja oraz relację jeden-do-jednego między nimi, co oznacza, że ​​każda notatka może mieć oznaczoną lokalizację. Następnie mam UITableView z pobranym kontroleremResultsController sterującym listą notatek (gdzie można dodawać nowe notatki i dołączać do nich datę i lokalizację), ale mam też dwa inne kontrolery widoku, jeden z widokiem mapy i jeden z widokiem kalendarza . Widok mapy pobiera wszystkie lokalizacje w lokalizacji i wyświetla je na mapie. Widok kalendarza w zasadzie odzyskuje wszystkie dane z Notatek i pokazuje je w widoku kalendarza. Jak śledzić zmiany w Notatkach i Lokalizacja w moim widoku kalendarza i mapy? Łatwo jest załadować je raz w viewDidLoad, ale jak mam śledzić wszystkie zmiany, aby po ponownym przejrzeniu mapy (np.) Zobaczył on również najnowsze dane.Najlepsze praktyki - NSManagedObjectContextObjectsDidChangeNotification w iOS

Jedynym sposobem, jaki odszyfrowałem, jest nasłuchiwanie powiadomień w NSManagedObjectContextObjectsDidChangeNotification, zarówno w widoku mapy, jak i widoku kalendarza. Wydaje się, że zwraca wszystkie wstawione, usunięte i zaktualizowane obiekty z zarządzanego kontekstu, za każdym razem, gdy jest zapis. Mógłbym wtedy przejść przez te obiekty i zobaczyć, czy muszę zaktualizować mój widok. Jest to, jak myślę to zrobić:

W MapViewController viewDidLoad:

[[NSNotificationCenter defaultCenter] 
    addObserver: self 
    selector: @selector(objectChangedNotificationReceived:) 
    name: NSManagedObjectContextObjectsDidChangeNotification 
    object: context]; 

Następnie:

- (void) objectChangedNotificationReceived: (NSNotification *) notification 
{ 
    NSArray* insertedObjects = [[notification userInfo] 
           objectForKey:NSInsertedObjectsKey] ; 
    NSArray* deletedObjects = [[notification userInfo] 
           objectForKey:NSDeletedObjectsKey] ; 
    NSArray* updatedObjects = [[notification userInfo] 
           objectForKey:NSUpdatedObjectsKey] ; 
    NSLog(@"insertObjects: %@", [insertedObjects description]); 
    NSLog(@"deletedObjects: %@", [deletedObjects description]); 
    NSLog(@"updatedObjects: %@", [updatedObjects description]); 

    for (NSManagedObject *obj in insertedObjects) { 
     if ([obj class] == [Location class]) { 
      NSLog(@"adding a new location"); 
      Location *locationObj = (Location *) obj; 
      [self.mapview addAnnotation: locationObj]; 
     } 
    } 
} 

Czy to wydaje się o prawo? Wygląda na to, że do każdego kontrolera widoku jest dużo zbędnego kodu, szczególnie jeśli interesuje mnie więcej niż jeden obiekt NSManagedObject. Czy jest jeszcze inna technika, której mi brakuje?

Odpowiedz

3

NSFetchedResultsController wydaje się spełniać twoje wymagania. Skutecznie zarządza przetwarzaniem danych z danych podstawowych. Ponownie używasz tego samego żądania pobierania zarówno dla kontrolera widoku kalendarza, jak i kontrolera widoku mapy.

+0

Skończyłem przy użyciu NSFetchedResultsController, mimo że moje widoki nie miały widok tabeli powiązane z nimi i działa jak charm! –

+0

@ZS Oczywiście 'NSFetchedResultsController' NIE musi być spokrewniony z tableView. –

2

Dlaczego nie można po prostu pobrać najnowszych danych bezpośrednio z CoreData w metodzie viewWillLoad lub viewDidLoad. Zapewni to, że masz najnowsze przedmioty.

Wygląda na to, że będzie bardziej modułowy i czystszy.

+1

Zbyt dużo kosztów. Tworzenie FRC, który słucha zmian dla ciebie, jest drogą do zrobienia. –