PopupButton, Bindings und Core Data

  • PopupButton, Bindings und Core Data

    Hallo alle,

    ich hab hier einen PopupButton der an einen ArrayController angeschlossen ist. Im Prinzip waehlt der Anwender hier unter einem Namen ein (Text)Template aus, das er dann noch weiter im NSTextView bearbeiten kann. Soweit funktioniert das auch, die Werte werden in der PopupButton Liste angezeigt, waehle ich einen aus wird zu dem Kuerzel im PopupButton ein Text in einen NSTextView eingetragen. Die Core Data Klasse des ArrayControllers besteht also aus den 2 Attributen name & text.

    Das Problem ist sobald ich den Text im NSTextView anpasse wird auch der Template Text geandert. Ist eigentlich auch klar, der TextView haengt an dem ArrayController mit dem Binding value=selection(des ArrayControllers). Der TextView duerfte also nicht direkt an dem ArrayController haengen. Ich habe schon versucht einen ObjectController dazwischen zu haengen, aber leider passieren da auch nur seltsame Sachen.

    Hat jemand ne Ahnung ?

    Gruesse

    Tom

    P.S. Hier noch die Werte der Bindings:

    PupoupButton
    content=arrangedObjects(ArrayController)
    contentValues=arrangedObjects.name(ArrayController)
    selectedIndex=selectionIndex(ArrayController)

    NSTextView
    value=selection.text(ArrayController)
  • Genau dafür sind Bindings ja da. Wenn du das TextField an die Templates bindest werden Änderungen natürlich mit übertragen.
    Ich hab jetzt nicht im Kopf, ob man das so einstellen kann, dass das TextField nur eine Kopie vom Template bekommt. Wenn das nicht geht musst du das wohl oder übel von Hand machen. Manchmal braucht's eben doch ein Zeilchen Code. ;)
  • RE: PopupButton, Bindings und Core Data

    Objective-C und Cocoa beruhen auf Referenzen. Objekte werdenn verzeigert, nicht kopiert. Zwei Zeiger auf dasselbe Objekt, zeigen auf dasselbe Objekt, nicht das Gleiche. Daher ist dieses Verhalten ganz natürlich und gewollt.

    Um das zu vermeiden, baue dir einen Copy-Setter, dies bedeutet einen Setter, der die Daten herüberkopiert. Dazu kannst du in der CD-Ansicht unter dem Menü Design->Data Model->Copy Implementation ... zunächst einen Setter erstellen lassen. Denn änderst du dann wie folgt:

    Quellcode

    1. - (void)setBoard:(NSString*)value
    2. {
    3. [self willChangeValueForKey: @"board"];
    4. [self setPrimitiveValue: [[value copy] autorelease] // Hier wird die Kopie erzeugt
    5. forKey: @"board"];
    6. [self didChangeValueForKey: @"board"];
    7. }
    Ist jetzt zwar trocken programmiert, müsste aber funktionieren.
    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"?
  • Das klappt so nicht da der TextView nicht an Core Data gebunden ist, nur der PopupButton (Zumindest wenn ich deinen Vorschlag richtig verstehe).

    Ich hab das aber als Anregung genommen und mir ueberlegt die TextView Klasse abzuleiten, und setString: zu ueberschreiben:

    Quellcode

    1. [self setValue: [[aString copy] autorelease] forKey: @"value"];
    Leider knallt's da mit einer SIGTRAP. :sick:
  • Sorry, da hab ich mich missverstaendlich ausgedrueckt. Der TextView haengt ebenfalls an dem Controller ueber das Binding value=selection, d.h. wird in dem PopupButton ein Wert gewaehlt aendert sich ja auch die selection Eigenschaft, also auch der Inhalt des NSTextView.

    Bei deinem Vorschlag wird ja der setter nicht durchlaufen, wegen obiger Bindung. Zum speichern des Wertes aus dem TextView greife ich den Wert direkt ab und fuege den einem komplexeren CD Objekt hinzu.

    Anyway, ich hatte eigentlich nur die Hoffnung das ich es ohne Code loesen kann. Per Code kann ich das dann selber frickeln.

    Dankeschoen :)
  • Wenn du es auch gebunden hast, dann ist es eben dasselbe Objekt. Dann wundert es nicht, wenn die Änderungen synchron sind. Wie gesagt: Das ist das gewollte Verhalten.

    Wieso werden aber die Setter nicht durchlaufen? Bindings nutzen KVC. KVC ruft Setter auf. Hast du es mal probiert?

    Dass es bei deiner "Lösung" nicht funktioniert, ist klar. Du erzeugst einen Stack-Overflow, weil du in dem Setter wiederum den Setter aufrufst. Ich habe ja in dem Parallelthread ne Graphik hinterlegt.
    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
    Wenn du es auch gebunden hast, dann ist es eben dasselbe Objekt. Dann wundert es nicht, wenn die Änderungen synchron sind. Wie gesagt: Das ist das gewollte Verhalten.

    Schon klar, aber nicht ganz das was ich brauche ;)

    Wieso werden aber die Setter nicht durchlaufen? Bindings nutzen KVC. KVC ruft Setter auf. Hast du es mal probiert?

    Jo, hab ich. Ist aber das erste mal das ich eine CD Klasse ueberschreibe, habs nur mal kurz getestet, vielleicht hab ich nen Fehler gemacht. Hab das wie in der Apple Doku (Managed Object Accessor Methods) gemacht. Klasse von NSManagedObject abgeleitet mit dem namen meine MO-Klasse, copy method declarations...,und den setter wie in deinem Bsp. ueberschrieben. Vielleicht hab ich was uebersehen...werds nochmal checken.
  • Ja, ich bin ja auch noch am lernen. Aber so langsam empfinde ich das auch als recht fehleranfaellig.

    Es ist mir auch schon ein paarmal passiert das ich von irgendwelchen tests noch Muell in den NIBs hatte, was dann zu seltsamen Effekten fuehrt. Im Code sieht man das recht schnell, bei den NIB's dauert das manchmal lange.

    Die wenigsten Probleme hatte ich bei GUI's bisher mit Access/VB. Da muss ich mal ehrlich sein ;)
  • VBA/Access kann auch schöne Stilblüten, aber das ist eiin anderes Thema.

    Das Problem scheint mir zu sein, dass hier ständig KVO, KVC, Bindings und CoreData zusammengerührt werden. Hier war es auch so. Der Aufruf von Settern hat *nichts* mit CoreData zu tun, sondern ist alleine ein KVC-Problem. Die Technologien sind erstaunlich unabhängig, ja teilweise auch unabhängig entstanden.

    Aber am Anfang sieht man die Struktur wohl noch nicht. Ich hatte das Glück, schon so lange dabei zu sein, dass die Dosen homöopathisch waren.

    Vllt ist es gar nicht schlecht, erst einmal ein paar Fingerübungen mit KVO und KVC manuelll zu machen, also ohne aufgesetzte Bindings und ohne CoreData. Wenn diese Basis abgearbeitet ist, versteht sich der Rest leichter.
    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"?
  • Hier mal ne Graphik und ein kleines Glossar:
    KVC
    Zugriff auf Entitäten. Man kann so etwas wie [anObject setValue:value forKey:@"schlüssel"] schreiben und so unabhängig auf Properties von Entities zugreifen. Dazu werden die Accessoren benutzt.

    KVO
    Der Zugriff auf Properties von Entitäten wird überwacht, wenn KVC oder auch die Setter benutzt werden.

    Bindings:
    Formalisierung von KVO; die gebundene Klasse observiert automatisch eine gegebene Eigenschaft an die Property einer Entität.

    Und nun zu etwas ganz anderem:
    CoreData
    Der Objektgraph kann graphisch modelliert werden. Persistenz wird geboten, Undoing. Die Properties einer Entity können mittels KVC gesetzt und KVO beobachtet werden.
    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"?