2011-05-24 13 views
6

Piszę aplikację, która ma cztery główne jednostki, które są połączone poprzez relacje. Niektóre z nich są jeden do jednego, niektóre są jednym do wielu. Po początkowym załadowaniu trzy podmioty ładują swoje dane z plików XML przechowywanych lokalnie do aplikacji, a jedna z nich pobiera XML z sieci i ładuje z niego swoje dane. Po załadowaniu aplikacji sprawdza, czy dane z każdego z tych plików są nowsze niż obecnie, a jeśli tak, zastąpi wszystkie aktualne dane w tym obiekcie danymi z odpowiedniego pliku.Powiązanie jednostki danych rdzenia nie zapisuje się między uruchomieniami

W ramach procesu debugowania podczas pisania wymuszałem usunięcie wszystkich danych. Kiedy wywoływana jest funkcja usuwania i wszystkie dane są ładowane przy uruchomieniu aplikacji, aplikacja działa pięknie, a wszystkie elementy i relacje zachowują się dokładnie tak, jak powinny. Jednak po usunięciu wywołania funkcji usuwania i przeprowadzeniu kontroli i próbie uruchomienia z przechowywanych danych, wszystkie relacje wydają się zanikać. Podczas debugowania tego stwierdziłem, że wszystkie jednostki zawierają wszystkie zwykłe dane, do których mają przypisywać, po prostu nie mają już relacji. Nie wiem, dlaczego na świecie relacje są zapisywane przy pierwszym obciążeniu, ale nie zachowują się, gdy wszystkie dane nie są ponownie importowane.

Wyobrażam sobie, że jakiś kod byłby przydatny dla każdego, kto debuguje, ale nie jestem pewien, ile powinienem uwzględnić. Zacznę od włączenia jednej z metod zwanych klasą ładowania danych. Jeśli cokolwiek innego mogłoby pomóc, daj mi znać. Wszelaka pomoc jest bardzo doceniana.

zaktualizowany kod: 25/02/11 (W oparciu o sugestie - nadal istnieje problem) zaktualizowany kod: 25.02.11 - problem rozwiązany

- (NSArray *) loadFeatures { 

    if ([self checkForUpdate:@"Features"]) { 

     [self deleteAllObjects:@"Features"]; 

     NSString *filePath = [self dataFilePath:FALSE withResourceName:@"Features"]; 
     NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:filePath]; 
     NSError *error; 
     GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error]; 

     NSArray *featureElements = [doc.rootElement elementsForName:@"FEATURE"]; 
     NSMutableSet *featureSections = [[NSMutableSet alloc] init]; 

     for (GDataXMLElement *featureElement in featureElements) { 

      NSString *featureName = nil; 
      NSNumber *featureSecure = nil; 
      NSNumber *featureID = nil; 
      NSNumber *featureSortKey = nil; 
      DisplayTypes *featureDisplayType = nil; 

      NSArray *names = [featureElement elementsForName:@"NAME"]; 
      if (names.count > 0) { 
       GDataXMLElement *firstName = (GDataXMLElement *) [names objectAtIndex:0]; 
       featureName = firstName.stringValue; 
      } else continue; 

      NSArray *secures = [featureElement elementsForName:@"SECURE"]; 
      if (secures.count > 0) { 
       GDataXMLElement *firstSecure = (GDataXMLElement *) [secures objectAtIndex:0]; 
       featureSecure = [NSNumber numberWithInt:firstSecure.stringValue.intValue]; 
      } else continue; 

      NSArray *featureIDs = [featureElement elementsForName:@"FEATUREID"]; 
      if (featureIDs.count > 0) { 
       GDataXMLElement *firstFeatureID = (GDataXMLElement *) [featureIDs objectAtIndex:0]; 
       featureID = [NSNumber numberWithInt:firstFeatureID.stringValue.intValue]; 
      } 

      NSArray *featureSortKeys = [featureElement elementsForName:@"SORTKEY"]; 
      if (featureSortKeys.count > 0) { 
       GDataXMLElement *firstSortKey = (GDataXMLElement *) [featureSortKeys objectAtIndex:0]; 
       featureSortKey = [NSNumber numberWithInt:firstSortKey.stringValue.intValue]; 
      } 

      NSArray *featureDisplays = [featureElement elementsForName:@"DISPLAYTYPEID"]; 
      if (featureDisplays.count > 0) { 
       GDataXMLElement *firstFeatureDisplay = (GDataXMLElement *) [featureDisplays objectAtIndex:0]; 

       for (DisplayTypes *thisDisplayType in self.displayTypes) { 
        if (thisDisplayType.displayTypeID == [NSNumber numberWithInt:firstFeatureDisplay.stringValue.intValue]) { 
         featureDisplayType = thisDisplayType; 
        } 
       } 
      } 

      NSArray *sectionElements = [featureElement elementsForName:@"SECTIONS"]; 


      for (GDataXMLElement *sectionElement in sectionElements) { 

       NSArray *sectionIDs = [sectionElement elementsForName:@"SECTION"]; 

       for (GDataXMLElement *sectionID in sectionIDs) { 
        NSArray *thisSectionIDs = [sectionID elementsForName:@"SECTIONID"]; 
        if ([thisSectionIDs count]) { 
         GDataXMLElement *thisSectionID = (GDataXMLElement *) [thisSectionIDs objectAtIndex:0]; 

         for (Sections *thisSection in self.sections) { 

          if ([thisSection.sectionID isEqualToNumber:[NSNumber numberWithInt:thisSectionID.stringValue.intValue]]) { 
           [featureSections addObject:thisSection]; 
          } 

         } 
        } 
       } 
      } 


      NSManagedObjectContext *context = [self managedObjectContext]; 
      NSManagedObject *featureInfo = [NSEntityDescription insertNewObjectForEntityForName:@"Features" inManagedObjectContext:context]; 
      [featureInfo setValue:featureName forKey:@"name"]; 
      [featureInfo setValue:featureSecure forKey:@"secure"]; 
      [featureInfo setValue:featureID forKey:@"featureID"]; 
      [featureInfo setValue:featureSortKey forKey:@"sortKey"]; 
      [featureInfo setValue:featureDisplayType forKey:@"display"]; 
      [[featureInfo mutableSetValueForKey:@"section"] unionSet:featureSections]; 

      NSError *error; 
      if (![context save:&error]) { 
       NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); 
      } 

      [[self.managedObjectContext objectWithID:featureDisplayType.objectID] addFeatureObject:featureInfo]; 
      [self.managedObjectContext save:&error]; 

      [featureSections removeAllObjects]; 


     } 

     [xmlData release]; 
     [doc release]; 
     [featureSections release]; 

    } 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Features" inManagedObjectContext:[self managedObjectContext]]; 
    [fetchRequest setEntity:entity]; 

    NSError *error; 
    NSArray *featureArray = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    [fetchRequest release]; 

    return featureArray; 

} 

UPDATE: 5/25/2011

Na życzenie publikuję kilka zrzutów ekranu.

1) Jest to, co otrzymuję podczas ładowania aplikacji po wszystkich danych została usunięta, a relacje są w takt

Data Loaded Properly

2) To, co mam, gdy aplikacja jest uruchamiana ponownie bez uprzedniego usuwanie i ponowne ładowanie danych. Zakładki na dole są tworzone przez jedną z encji i mają nieco inny tytuł. Dzieje się tak, ponieważ związek z typem DisplayType nie występuje i nie ma informacji o typie kontrolera widoku, który ma zostać załadowany, i nie wie, której ikony należy użyć dla tej karty.

Data Loaded - Relationships Missing

Odpowiedz

3

Zazwyczaj nie trzeba jawnie ustawione z obu stron relacji. Kiedy masz do czynienia z relacją wiele-do-siebie, prawdopodobnie bezpieczniej jest dodać jedną jednostkę naraz do kolekcji, zamiast ustawiać całą kolekcję naraz. Tak więc, zamiast:

[featureInfo setValue:[NSSet setWithSet:featureSections] forKey:@"section"]; 

bym pętla przez zestaw featureSections i dodać każdy obiekt, jeden po drugim do section relacji podmiotu Feature, np:

for (Sections *aSection in featureSections) { 
    // use the automatically-generated relationship mutator   
    [featureInfo addSectionsObject:aSection]; 
} 

Mam nadzieję, że to pomoże ..

W przeciwnym razie może być interesujące w dokumentacji Apple this section.

+0

Dziękuję za odpowiedź.Jedynym problemem z zaleceniem, które widzę, jest to, że featureInfo jest członkiem klasy NSManagedObject, a nie klasy Features, a zatem nie ma metody elementu "addSectionsObject:" - na pewno przejrzę dokumentację. – unclesol

+0

Próbowałem to zaimplementować w kodzie poniżej początkowej wstawki, gdzie obiekt jest pobierany. Zamiast ładować tę funkcję jako funkcję wyświetlania, właśnie przesunąłem wartość setValue do tego punktu. Niestety, wydaje się, że nie miało to żadnego wpływu. – unclesol

+0

You * do * masz dostęp do dynamicznie generowanych akcesorów, takich jak 'addSectionsObject:' nawet jeśli pracujesz z instancjami 'NSManagedObject'. (Zobacz, jak wyjaśnić i jak ukryć ostrzeżenia kompilatora: http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html#//apple_ref/doc/uid/TP40002154 -SW9). – octy

Powiązane problemy