2016-05-26 20 views
8

Ich versuche, meine Coredata-Modell für diese Situation zu entwerfen:NSFetchedResultsController Komplex Abrufanforderung und Modell

Wir haben Song Objekt, das mit einigen List-Beziehung haben.

Jedes List haben name Eigenschaft und auch zu-viele-Beziehung haben mit Song

Diese many-to-many-Beziehung ist erforderlich, da ein Song kann in jedem List zugleich präsentiert werden.

Ich brauche irgendwie Liste der Song s durch diesen Header (Name des List) mit NSFetchedResultsController gruppiert zu erhalten (da Benutzer 10.000 Songs haben kann, und ich will es nicht in NSArray irgendwo speichern).

Wenn ich versuche, sectionNameKeyPath: mit einem Wert, z. @"List.name" Ich habe einen Fehler "to-many Beziehung ist nicht erlaubt" und das macht natürlich Sinn.

Also muss ich helfen, wie mein Modell zu entwerfen zu können, Song s haben und einige List s wie „Geschichte“/usw. und in der Lage sein zu holen alle Daten mit NSFetchedResultsController „Next Spielen“.

Jede Hilfe wird geschätzt. Wenn meine Erklärung nicht klar war, bitte fragen Sie nach weiteren Informationen.

Teil meiner Code:

- (void)initFetch { 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Song"]; 

    [fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]]; 
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"ANY [email protected] != 0"]; 
    fetchRequest.fetchBatchSize = 20; 

    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:@"name" cacheName:nil]; 
    [self.fetchedResultsController setDelegate:self]; 

    NSError *error = nil; 
    [self.fetchedResultsController performFetch:&error]; 

    if (error) { 
     NSLog(@"Unable to perform fetch."); 
     NSLog(@"%@, %@", error, error.localizedDescription); 
    } 
} 

Antwort

0

Sie brauchen keine FRC verwenden übermäßige Laden von Daten zu verhindern, ist es nicht das, was das tut. Die Stärke des FRC liegt in der Beobachtung des Kontextes, um Veränderungen zu erkennen. Diese Leistung funktioniert auch nicht gut, wenn Sie versuchen, durch Beziehungen zu navigieren, so dass Sie in diesem Fall wahrscheinlich auch keinen FRC nutzen werden.

Ihre Datennutzung beschränkt sich auf verwaltete Objekte, wenn sie nicht mehr benötigt werden (in einigen Fällen manuell, aber das System wird dies bei Bedarf selbst tun) und auf das Stapeln der Abrufanforderung. Wenn Sie eine Stapelgröße für die Abrufanforderung festlegen, wird die zurückgegebene NSArray nur Daten in den Speicher laden. Der FRC profitiert davon, kontrolliert ihn aber nicht - und wenn Sie vergessen, die Charge hinzuzufügen, wird der FRC das nicht für Sie tun!

Sie können also entweder ein System einrichten, in dem Sie mehrere Arrays haben, 1 pro Abschnitt, und alles selbst verwalten. Oder Sie könnten mehrere FRCs 1 für jeden Abschnitt verwenden und die Indexpfade so manipulieren, dass alles zusammen hängt.

Oder könnten Sie Ihr Datenmodell ändern, indem Zwischen Hinzufügen von Objekten, die die Zugehörigkeit zu einem Song in einem List darstellen, da dies die many-to-many-Beziehungen brechen würde und lassen Sie mit einer schiffbaren Beziehung in früher und sortiert Deskriptoren . In diesem Fall wäre die neue Entität diejenige, die Sie für die FRC abgerufen haben. Beachten Sie das oben erwähnte Problem über Änderungsverfolgung über Beziehungen hinweg, achten Sie darauf, was Sie ändern und wie ...

+0

danke für den Kommentar, aber ich sollte nicht mit Ihrer Aussage über FRC würde nicht helfen, Speichermenge zu reduzieren. Zum Beispiel kann meine App jetzt eine Playlist mit mehr als 20000 Songs enthalten. Wenn ich alle diese Datensätze abrufe, stürzt die App ab. Ich mag keine Idee, dieses ganze Zeug manuell zu managen, und ich habe keine Ahnung, wie man das macht :) Auch [@ Brads Antwort] (http://stackoverflow.com/a/1263845/1263701) stellen Sie fest, dass FRC in meiner Situation sehr nützlich ist. – zakhej

+1

Brads Antwort ist völlig richtig, es sagt auch das gleiche wie ich über die Abruf Batch-Größe, die der Schlüssel zur Speicherverwaltung ist. Er behandelt jedoch nicht die Beziehungen, und das ist es, was ich beziehe und womit du ein Problem hast. Ich würde empfehlen, Ihr Datenmodell zu ändern ... – Wain

+0

Ich sehe nicht, warum das Brechen des n: m in Zwischenobjekte helfen kann. Es ist kein Problem der Implementierung der n: m-Beziehung. Ich würde jedoch empfehlen, auch mehrere FRC zu verwenden. –

1

Die Verwendung von FRC kann hervorragend für die Anzeige von Daten für Ihren Benutzer sein, aber bei der Verwendung kann es diktieren, wie Ihr Modell strukturiert sein muss und nicht wie Sie sonst Ihre Strukturelemente und Beziehungen strukturieren könnten. In deinem Fall sieht es so aus, als ob du eine Liste von aktuellen States für Songs in deiner Datenbank sehen möchtest anstatt einer Liste a von Songs. Jede Zustandsinstanz würde eine Eins-zu-Eins-Beziehung zu einem Lied haben, und der Zustand könnte eine Eins-zu-Viele-Beziehung in Ihren Listen haben, z. mit einer History-Liste verbunden sein, playNext list, zZ spielen "list" (mit nur einer Instanz im letzten Fall). Wenn Sie Ihre FRC-Entität auf diesen State Entitäts- und Abschnittsschlüsselpfad festlegen, der mit der Liste verknüpft ist, in der sich der Status befindet, können Sie die obige Anforderung erfüllen, ohne indexPaths bearbeiten oder mit mehreren FRCs arbeiten zu müssen. Wenn Sie diese separate Entität verwenden, können Sie später weitere Attribute hinzufügen, z. B. das Datum der letzten Wiedergabe oder ein Aggregat für die Wiedergabezeit. All dies könnte auf der State-Entity statt auf der Song-Entity selbst erfolgen.

+0

Dies ist eine ausführliche Beschreibung einer der Optionen in meiner Antwort, die es ziemlich gut erklärt, aber ich würde nicht staatliche Instanzen wiederverwenden, weil das Management macht und die Verwendung schwieriger (eine eins-zu-eins-Beziehung bedeutet, dass es trivial ist, den Namen der Liste zu bekommen, und es ist einfach, den Status zu löschen, wenn es nicht mehr benötigt wird - und es kann mit einer Löschregel gemacht werden) – Wain

+0

Ich stimme zu ich meine die Zustandsinstanzen wiederzuverwenden. Ich meinte, dass jede Instanz eines Bundesstaats eine Verbindung zu einer Liste herstellen und dann eine neue Zustandsinstanz erstellen würde, wenn sich etwas ändert. Ich denke, ich habe das nicht gut erklärt. Ich habe auch Ihre Antwort noch einmal gelesen und festgestellt, dass die letzte Option, die Sie erwähnten, das Objekt "intermediate" ist die gleiche Art von Lösung, die ich hier vorgeschlagen hatte. –