CoreData - NSTreeController

  • Du müsstest schon etwas mehr Code posten. Aber so wie das ausseht:

    Ein Kind einees Outline-Items ist eine Entität. Diese Entität hat eie Beziehung (wrwa neben dem Attribut title), welches die Anzahl der Kinder ermittelt. Daher wird numberOfChildren nicht an eine Collection, sondern an eine Entität geschickt

    Einfach gesagt: Du gibst auf oberster Ebene mutmaßlich statt einer Entitäts-Ansammlung einfach gleich den Container zurück. Damit kann das Outline-View nichts anfangen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von Tom9811
    Einfach gesagt: Du gibst auf oberster Ebene mutmaßlich statt einer Entitäts-Ansammlung einfach gleich den Container zurück. Damit kann das Outline-View nichts anfangen.


    Ich weiß.
    Original von me, myself and I
    Kein Wunder, schließlich kennt das Array mit den Kindelementen die Methode 'numberOfChildren' nicht. Woher auch, reicht ja wenn das Kindelement diese kennt.


    Der Code an sich läuft prima (auch wenn ich da sicherlich an einigen Stellen suboptimal gefrickelt habe).
    Es geht mir auch gar nicht um den Code als Spezielles sondern um einen Lösungsansatz im Allgemeinen.

    Ich möchte nur einfach mehrere Wurzeln im OutlineView haben.
    Siehe Xcode. Hat Ressources, SCM, Target und so weiter, alles als eigene Wurzel.
    Der Class Browser im IB2 ebenfalls. Und iTunes bei den selbst angelegten Ordnern. Sogar der dusselige Finder...

    Wenn das nicht geht (wovon ich ausgehe), dann möchte ich wenigstens die Anzeige der Oberwurzel, nennen wir sie 'root', unterbinden.

    Nur wo?
    (Anmerkung des Verfassers: momentan erzeuge ich den TreeController im Code und füttere das OutlineView mit ner DataSource. Sobald die Grunddinge laufen, will ich das auf Bindings umstellen. Es wäre also schön, gäbe es einen Lösungsansatz, der in beiden Fällen laufen wird.
    Wozu? Um Core Data zu kapieren. Eines habe ich schon begriffen: das Objektgefrickel nervt. ^^)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Original von Lucas de Vil
    In den Attributes des NSTreeController muss folgendes Predicate gesetzt werden:

    Quellcode

    1. parent == nil


    Original von Tom9811
    Diese Lösung ist ja etwas schräg. Erst werden alle Instanzen der Entität genommen und dann wiederum diejenigen herausgefiltert, die nicht die obersten sind. Das ist ja ein bisschen von hinten durch die Brust ins Auge.


    +hm+
    developer.apple.com/samplecode/AbstractTree/listing6.html
    Darin findet sich ein Bild wie im Anhang.
    Da frage ich mich doch ganz beherzt: und nu?
    War mein Ansatz etwa doch nicht so schräg?
    Ich meine, das ist ein 10.5 Tutorial. So langsam sollten die schon wissen was sie tun. Und sie tun es genau so wie ich es tat.

    Ich steh' auf dem Schlauch, wer schubst mich runter? ?(
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Du kannst es dir selbst ausmalen:
    Du hast 5 oberste Knoten und darunter eine Struktur mit 100.000 Einträgen.

    Wie viele Zugriffe benötigst du, um die 5 geschlossenen Knoten herauszufischen?
    Ich tippe grob geschätzt auf 100.005 …

    Ja, einfach ist das so. Ja, gut ist das so nicht.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • CoreData -NSTreeController

    Original von Tom9811
    Es wird mutmaßlich deshalb gemacht, weil es einfach ist.


    Hallo Tom,

    hast Du noch Deinen Sample-Code vom Anfang des Threads, oder könntest Du es kurz zusammen klicken, wenn es wirklich nur 10 Minuten dauert. Ich stehe vor dem gleichen Problem und habe mich bisher an das Beispiel von Apple gehalten, würde es aber gerne sauber programmieren.

    Ralph.
  • RE: CoreData -NSTreeController

    Original von RalphM
    Original von Tom9811
    Es wird mutmaßlich deshalb gemacht, weil es einfach ist.


    Hallo Tom,

    hast Du noch Deinen Sample-Code vom Anfang des Threads, oder könntest Du es kurz zusammen klicken, wenn es wirklich nur 10 Minuten dauert. Ich stehe vor dem gleichen Problem und habe mich bisher an das Beispiel von Apple gehalten, würde es aber gerne sauber programmieren.

    Jetzt hier auf dem Rechner gewiss nicht, vielleicht zu hause. Muss ich heute abend nachschauen, habe da aber meine Zweifel. :(

    Zur Klarstellung: Das, was Apple macht, ist nicht falsch. Es führt eben nur zu einem bestimmten Verhalten, welches man in der Regel nicht will.

    Wenn du den gesamten Thread nacharbeitest, müsstest du ihn aber auch selbst schreiben können. (Ich bin derzeit ziemlich im Brassel, sorry.)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • RE: CoreData -NSTreeController

    Original von Tom9811
    Original von RalphM
    Ich stehe vor dem gleichen Problem und habe mich bisher an das Beispiel von Apple gehalten, würde es aber gerne sauber programmieren.

    Jetzt hier auf dem Rechner gewiss nicht, vielleicht zu hause. Muss ich heute abend nachschauen, habe da aber meine Zweifel. :(

    Zur Klarstellung: Das, was Apple macht, ist nicht falsch. Es führt eben nur zu einem bestimmten Verhalten, welches man in der Regel nicht will.


    Und ich verstehe bis heute nicht, was an diesem Verhalten in der Regel nicht gewollt ist. +seufz+
    Ich meine, das blöde Outline-View bekommt alle Objekte reingeworfen - und fertig.

    Dieses komische Predicate steuert doch bloß die Art und Weise, in der der Inhalt dargestellt werden soll. Oder etwa nicht? ?(

    Es ist doch vollkommen sinnlos, sich endlos Gedanken darum machen zu müssen wie man jetzt _ein_ NSObject automatisch bei Programmstart in den Controller packt, auswählt und dann das OutlineView dessen Selection anzeigen lässt. Oder etwa nicht?

    Der programmatische Unterschied mag in der Tat marginal sein.
    Ob ich jetzt mit der Apple-Methode arbeite und die parent-Elemente der ToDo-Items 'Homepage', 'Software', 'Finanzen' und 'Wohnung' nenne oder ob ich vier Objekte namens 'Homepage', 'Software', 'Finanzen' und 'Wohnung' habe, die jeweils ToDo Items beinhalten - es ändert nicht viel an der Funktionalität.

    Wohl aber an der Übersicht, schließlich muss ich jedes Mal das gewollte Objekt selektieren. Das finde ich voll umständlich.

    Eigentlich möchte ich folgende Darstellung in meinem Programm:

    Quellcode

    1. + Homepage
    2. - Software
    3. - Buch zu OOA&D zu Ende lesen
    4. - Übungsprogramme schreiben
    5. - NSOutlineView kapieren
    6. + Finanzen
    7. - Wohnung
    8. - Besichtigungstermine aushandeln
    9. - Tapezieren
    10. - Streichen


    All diese Punkte liegen in der Datei 'private.todolist'.
    Die 'geschäftliche.todolist' ist eine völlig andere Datei mit mitunter völlig unterschiedlichen Punkten. Ich muss also gar nicht lange irgendwelche Objekte auswählen, die Datei selbst ist ja die Selektion, die ich anzeigen möchte.

    Da steht mir der Aufwand in keinem Verhältnis zum Nutzen.
    Die Apple-Methode sagt mir: beschränke die Anzeige im View auf Elemente, die kein Elternelement haben. Füge dann deine ToDoList Items hinzu.

    Die Objektmethode sagt mir: WENN eine neue Datei erstellt wird, initialisiere ein Objekt im ObjectController und selektiere es. Füge dann deine ToDoList Items hinzu.
    WENN eine bereits vorhandene Datei geöffnet wird, selektiere das einzige Objekt im ObjectController. Füge dann deine ToDoList Items hinzu.
    (und die beiden WENNs machen mir am Meisten Kopfzerbrechen...)

    Zusammengefasst: Ich hab so das dumpfe Gefühl, dass sich der Sinn und Zweck der Funktionsweise des OutlineViews vor mir verbirgt...

    RalphM: Du kannst mir auch gern eine Mail schreiben, ich habe das Archiv noch auf meinem Rechner rumflattern. :)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RE: CoreData -NSTreeController

    Du kannst es dir selbst ausmalen:
    Du hast 5 oberste Knoten und darunter eine Struktur mit 100.000 Einträgen.

    Wie viele Zugriffe benötigst du, um die 5 geschlossenen Knoten herauszufischen?
    Ich tippe grob geschätzt auf 100.005 …


    Und woher weißt du das?
    Ich setze dagegen: es braucht genau 5 Zugriffe, da jedes Kindelement per Definition ein Elternteil hat und deshalb gar nicht weiter rausgefischt werden muss - die Kindelemente brauchen also gar nicht erst gefragt werden, ob sie vielleicht ein Parent-Element haben.

    //edit_ Mich hat der Probierwahn gepackt, nach dem Essen wird was getestet...
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RE: CoreData -NSTreeController

    Woher soll denn der Fetch wissen, ob nicht an Stelle 87.343 der Tabelle nicht doch noch eine Instanz kommt, bei der parent == nil ist?

    Ein Fetch holt dir alle Instanzen einer Entität. Wenn du ihm ein Prädikat gibst, wird anhand des Prädikats gefiltert. Um festzustellen, ob die Bedingung erfüllt ist, muss die Instanz erst einmal geladen werden.

    Wenn du SQL benutzt, wird diese Aufgabe freilich auf die SQL-Engine verlegt. Und was macht die? Die schaut sich alle 100.000 Instanzen an. Du weißt doch selbst, wie das mit SQL-Engines funktioniert.

    SELECT * FROM nodes WHERE parent == nil

    Was macht da die Engine?
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • RE: CoreData -NSTreeController

    Original von Tom9811
    Woher soll denn der Fetch wissen, ob nicht an Stelle 87.343 der Tabelle nicht doch noch eine Instanz kommt, bei der parent == nil ist?

    Ein Fetch holt dir alle Instanzen einer Entität. Wenn du ihm ein Prädikat gibst, wird anhand des Prädikats gefiltert. Um festzustellen, ob die Bedingung erfüllt ist, muss die Instanz erst einmal geladen werden.

    Wenn du SQL benutzt, wird diese Aufgabe freilich auf die SQL-Engine verlegt. Und was macht die? Die schaut sich alle 100.000 Instanzen an. Du weißt doch selbst, wie das mit SQL-Engines funktioniert.

    SELECT * FROM nodes WHERE parent == nil

    Was macht da die Engine?



    Genau das ist der Punkt, ich möchte nicht, dass meine Core-Data Anwendung erst 20.000 Datensätze liest, um dann zu entscheiden, bei welchen parent == nil ist.
  • RE: CoreData -NSTreeController

    Original von RalphM
    Original von Tom9811
    Woher soll denn der Fetch wissen, ob nicht an Stelle 87.343 der Tabelle nicht doch noch eine Instanz kommt, bei der parent == nil ist?

    Ein Fetch holt dir alle Instanzen einer Entität. Wenn du ihm ein Prädikat gibst, wird anhand des Prädikats gefiltert. Um festzustellen, ob die Bedingung erfüllt ist, muss die Instanz erst einmal geladen werden.

    SELECT * FROM nodes WHERE parent == nil

    Was macht da die Engine?



    Genau das ist der Punkt, ich möchte nicht, dass meine Core-Data Anwendung erst 20.000 Datensätze liest, um dann zu entscheiden, bei welchen parent == nil ist.


    Aber ich denke, CoreData sei kein rDBMS.
    Es ist ein verf***ter Objektgraph, oder?
    Dann habe ich keine Tabelle mit 87.398 Einträgen, bei der an Stelle 87.343 eine Instanz mit parent == nil kommt.
    Dann habe ich 15 Objekte mit jeweils ca. 35 Unterobjekten, die jede im Schnitt 125 Unterobjekte haben, die jeweils ungefähr 1,3333333333333333 Unterobjekte haben.

    Und da diese 15 Objekte jeweils parent == nil haben zeige ich sie an.
    Da ihre Kinder nie nicht auf überhaupt gar keinen Fall parent == nil haben können frag ich die auch gar nicht erst. Das Fragen der Kindeskinder kann ich mir dann auch sparen.

    SO verstehe ich die Funktion von NSOutlineView, weshalb mich das Verhalten eben dessen, wirklich alles anzuzeigen verwirrt hat. Ich sehe da einfach überhaupt keinen Sinn und Verstand drin.


    Ich will die Anzeige rechts, ohne den Blödsinn links.

    Denn was macht das großartig anders?
    Es schränkt die Auswahl auf eine Selektion ein. Und?
    Trotzdem habe ich Objekte mit Unterunterunterunterobjekten.
    Wieso zeigt er sie bei dem Beispiel nicht mit an?

    Wenn mir doch nur eine Möglichkeit einfallen würde auszuwerten, welche Objekte dieses blöde NSOutlineView jetzt tatsächlich _läd_, nicht nur _darstellt_.

    Denn der Zugriff auf eine Art Tabelle führt die Verwendung von Objekten für mich ad adsurdum.
    Du siehst, ich tue mich wirklich schwer mit dem blöden View. :D
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RE: CoreData -NSTreeController

    Jepp. Häufig genug (aka fast immer) stellt sich das Problem allerdings gar nicht erst: Auf oberster Ebene hast du nämlich meist so etwas wie "Bibliothek", "Playlist", die bereits von sich aus eine andere Entität sind, weil sie ganz andere Attribute haben.

    Da muss man schon kräftig quetschen, um eine Playlist als die gleiche Entität wie die enthaltenen Songs anzusehen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • RE: CoreData -NSTreeController

    Ist es ja auch nicht Aber auch Core Data muss erst ein Objekt haben, um zu berurteilen, wie eine bestimmte Eigenschaft gesetzt ist. Meinst du, Core Data hat eine Kristallkugel?

    Dabei spielt es nicht die geringste Rolle, ob dahinter ein XML-Store ist, eine SQl-Engine, das Internet oder Excel. Wenn ich die Eigenschaft wissen will, muss ich mir zunächst das Objekt besorgen, auf welcher Ebene von wem auch immer. Das ist ja keine Frage der Implementierung, sondern der Denkgesetze.

    Es geht auch nicht im die obersten Elemente im Outline-View. Die willst du doch erst erfahren. Woher kommen die denn? Herbeigezaubert? Vorhergesehen? Damit dein Outline-View überhaupt erst einmal seine oberste Ebene kennt, muss es alle Instanzen der Entität durchsuchen. Woher soll es sie denn sonst kennen? Danach muss man nicht erneut suchen, das stimmt. (Wenn sich nichts geändert hat, was das Outline-View woher weiß? Richtig, es müssen dazu alle 100.000 Objekte observiert werden. Ich gehe hier aber davon aus, dass das auf das Faulting optimiert ist.)

    Mit den Views hat das übrigens genau gar nichts zu tun. Die Filterung erfolgt ja bereits im Controller. Allerdings wird das View nie die geschlossenen Objekte abfragen, so dass sich diese mutmaßlich im Fault befinden.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • RE: CoreData -NSTreeController

    Original von Tom9811
    Jepp. Häufig genug (aka fast immer) stellt sich das Problem allerdings gar nicht erst: Auf oberster Ebene hast du nämlich meist so etwas wie "Bibliothek", "Playlist", die bereits von sich aus eine andere Entität sind, weil sie ganz andere Attribute haben.


    Und das in ein und demselben OutlineView?!?
    Ich geh kaputt, kommt wer mit?
    (aka what the fuck? Wie dat dann?)

    Original von Tom9811
    Ist es ja auch nicht Aber auch Core Data muss erst ein Objekt haben, um zu berurteilen, wie eine bestimmte Eigenschaft gesetzt ist. Meinst du, Core Data hat eine Kristallkugel?


    Bestimmt, wenngleich nicht sonderlich optimiert. :P ;)
    Der Jung (aka die Datei, die den Graphen enthält) speichert also alle Objekte einzeln untereinander wech und gibt nur jedem mit auf dem Weg, wer zu ihm und zu wem er gehört.
    Der Controller sammelt sich dann das Ganze zusammen und bastelt sich daraus die Art von Graphen, mit der er arbeiten kann.

    Während der ArrayController also versucht ist, das ganze Datengelump in viele NSMutableArrays zu stopfen will der TreeController daraus eine Baumstruktur flechten. Dem ObjectController hingegen ist das alles wurscht, er nimmt sich nur einfach ein Objekt davon (theoretisch, praktisch weiß ich nicht, was er mit den 87.973 anderen Objekten tut - will ich grad auch gar nicht).

    Sollte bis hier kein gravierender Denkfehler vorliegen, dann habe ich eines noch nicht gerafft:
    Wieso tritt das Verhalten nicht auf, wenn der Controller an die Selektion eines ObjektControllers gebunden ist?

    Klar, das Objekt hat meinetwegen eine Relationship zu zwei Items, welche eine Relationship zu 10 Items haben welche insgesamt zu 2.785 Items eine Relationship haben, was halt diese Baumstruktur darstellt. Im Prinzip aber nichts anderes als wenn er sich das so aus der Datei lädt.

    Oder definiert die Selection aus dem ArrayController schon von vorn herein, was jetzt das Parent-Element ist und was nicht?
    Falls ja: wie kann ich das ohne große Umwege abbilden?


    Wie gehabt: ich möchte die Anzeige auf der rechten Seite ohne den Kram auf der Linken.
    Was wäre dein Lösungsansatz dafür?
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • RE: CoreData -NSTreeController

    Wirf mal einen Blick in Mail.App. Bei mir ist das ziemlich in einer Baumstruktur. Und ich glaube nicht, dass die Einträge auf oberster Ebene die gleiche Entität sind, wie die enthaltenen.

    Dann startest du iTunes.

    Danach ist Xcode dran.

    Ich sehe da ganz viel Heterogenes.

    Ich würde das genau so modellieren. (Es ist meist das Beste, etwas so zu machen, wie es ist.)

    Also: Auf oberster Ebene wirst du Karteikästen, Themengebiete oder ähnliches haben. Ich kenne deine App ja nun nicht. Also modellierst du eine Entität, sagen wir Karteikästen oder Themengebiete. Hier hast du 5 Eiträge. Diese werden auch komplett bei Start des Programmes geladen. Es sind nur 5.

    Wenn einer geöffnet wird, werden die Verweise (children) diesesEintrages geladen, also vielleicht 10. Wenn du darin einen öffnest, werden dessen Einträge geladen, also vielleicht 17.

    Aber niemals werden alle geladen, also vielleicht 100.000.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?