4

in meinem iPhone-Anwendung Ich verwende einfache Core Data-Modell mit zwei Entitäten (Artikel und Property):Kerndaten: Holen Sie alle Entitäten in einer zu-viele-Beziehung eines bestimmten Objekts?

Artikel
Name
Eigenschaften

Immobilien
Name
Wert Artikel

Artikel hat ein Attribut (Name) und eine Eins-zu-viele-Beziehung (Eigenschaften). Seine inverse Beziehung ist Element. Eigenschaft hat zwei Attribute die entsprechende umgekehrte Beziehung.

Jetzt möchte ich meine Daten in Tabellenansichten auf zwei Ebenen zeigen. Der erste listet alle Gegenstände auf; Wenn eine Zeile ausgewählt ist, wird ein neuer UITableViewController auf den Stack meines UINavigationControllers geschoben. Die neue UITableView soll alle Eigenschaften (d. H. Ihre Namen) des ausgewählten Elements anzeigen.

Um dies zu erreichen, verwende ich eine NSFetchedResultsController in einer Instanzvariable gespeichert. Auf der ersten Ebene, funktioniert alles einwandfrei, wenn die NSFetchedResultsController wie diese Einrichtung:

-(NSFetchedResultsController *) fetchedResultsController { 
    if (fetchedResultsController) return fetchedResultsController; 

    // goal: tell the FRC to fetch all item objects. 
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init]; 

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.moContext]; 
    [fetch setEntity:entity]; 

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
    [fetch setSortDescriptors:[NSArray arrayWithObject:sort]]; 

    [fetch setFetchBatchSize:10]; 

    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"]; 
    self.fetchedResultsController = frController; 
    fetchedResultsController.delegate = self; 

    [sort release]; 
    [frController release]; 
    [fetch release]; 

    return fetchedResultsController; 
} 

jedoch auf der zweiten Ebene UITableView, scheine ich etwas falsch zu tun. Ich implementierte den fetchedresultsController auf ähnliche Weise:

-(NSFetchedResultsController *) fetchedResultsController { 
    if (fetchedResultsController) return fetchedResultsController; 

    // goal: tell the FRC to fetch all property objects that belong to the previously selected item 
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init]; 

    // fetch all Property entities. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.moContext]; 
    [fetch setEntity:entity]; 

    // limit to those entities that belong to the particular item 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"item.name like '%@'",self.item.name]]; 
    [fetch setPredicate:predicate]; 

    // sort it. Boring. 
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
    [fetch setSortDescriptors:[NSArray arrayWithObject:sort]]; 

    NSError *error = nil; 
    NSLog(@"%d entities found.",[self.moContext countForFetchRequest:fetch error:&error]); 
    // logs "3 entities found."; I added those properties before. See below for my saving "problem". 
    if (error) NSLog("%@",error); 
    // no error, thus nothing logged. 

    [fetch setFetchBatchSize:20]; 

    NSFetchedResultsController *frController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.moContext sectionNameKeyPath:nil cacheName:@"cache"]; 
    self.fetchedResultsController = frController; 
    fetchedResultsController.delegate = self; 

    [sort release]; 
    [frController release]; 
    [fetch release]; 

    return fetchedResultsController; 
} 

Jetzt wird es komisch. Die obige NSLog-Anweisung gibt mir die korrekte Anzahl von Eigenschaften für das ausgewählte Element zurück. Allerdings sagt die UITableViewDelegate Methode mir, dass es derzeit keine Immobilien:

-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; 
    NSLog(@"Found %d properties for item \"%@\". Should have found %d.",[sectionInfo numberOfObjects], self.item.name, [self.item.properties count]); 
    // logs "Found 0 properties for item "item". Should have found 3." 
    return [sectionInfo numberOfObjects]; 
} 

Die gleiche Umsetzung arbeitet auf der ersten Ebene in Ordnung.

Es wird noch seltsamer. Ich habe eine Art von UI implementiert, um Eigenschaften hinzuzufügen. Ich erstelle eine neue Property Instanz über Property *p = [NSEntityDescription insertNewObjectForEntityForName:@"Property" inManagedObjectContext:self.moContext];, richte die Beziehungen ein und rufe [self.moContext save:&error] an. Dies scheint zu funktionieren, als error ist immer noch nil und das Objekt wird gespeichert (ich kann die Anzahl der Eigenschaften bei der Protokollierung der Artikel Instanz sehen, siehe oben). Die Delegate-Methoden werden jedoch nicht ausgelöst. Dies scheint mir aufgrund der möglicherweise durcheinander geraten fetchRequest (Controller).

Irgendwelche Ideen? Habe ich die zweite Fetch-Anfrage durcheinander gebracht? Ist dies der richtige Weg, um alle Entitäten in einer to-many-Beziehung für eine bestimmte Instanz abzurufen?

Antwort

2

Sie tatsächlich benötigen, um den Abruf für den Tabelle View-Controller ausführen:

// ...create the fetch results controller...  
NSError *fetchRequestError; 
BOOL success = [fetchedResultsController performFetch:&fetchRequestError]; 
+0

Way ... zu ... einfach. Vielen Dank, ich sollte einen Kaffee trinken gehen.:) –

+0

Nun, es ist ein kleines bisschen Code in der Mitte einer ganzen Reihe von anderen Code stecken. Core Data ist ein kompliziertes Biest. –

+0

Sorry, ich bin ein wenig verwirrt, welche Zeile ersetzt das Code-Snippet? – jklp

Verwandte Themen