Predicate auf NSArrayController anwenden und immer informiert bleiben

  • Predicate auf NSArrayController anwenden und immer informiert bleiben

    Hallo,

    nochmal ein Problemchen...

    In meiner Anwendung gibt es Einträge, die in einem TableView angezeigt werden. Man kann Einträge aktivieren und deaktivieren - siehe Screenshot.

    Nun bräuchte ich einen NSArrayController, der immer nur die aktivierten Objekte enthält.

    Wie ich es gemacht habe:

    In einem meiner Controller schrieb ich folgendes:

    Quellcode

    1. - (NSPredicate *)activatedObjectsPredicate
    2. {
    3. return [NSPredicate predicateWithFormat:@"activated == 1"];
    4. }


    Dann habe ich mir einen neuen NSArrayController geholt. Dessen contentArray an einen anderen NSArrayController gebunden, der alle Elemente enthält - egal ob aktiviert oder deaktiviert. Und dann noch das filterPredicate auf meinController. activatedObjectsPredicate gesetzt. Das klappt auch ganz gut - allerdings muss sich immer zunächt der content des NSArrayControllers ändern, der alle Objete enthält - egal ob aktiviert oder deaktiviert.

    Das Ganze arbeite gemeinsam mit Core Data.

    Danke.
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • RE: Predicate auf NSArrayController anwenden und immer informiert bleiben

    Es handelt sich mal wieder um das "Array-Überwachungs-Problem". Wenn man etwas an einen ArrayController bindet, dann werden nur Änderungen am Array (hinzufügen, löschen, verschieben von Objekten) überwacht. Änderungen an den Objekten in dem Array sind aus Sicht der Cocoa-Bindings keine Änderung des Arrays! Das Problem hatten wir hier in letzter Zeit öfters besprochen.

    Michael
  • RE: Predicate auf NSArrayController anwenden und immer informiert bleiben

    Original von Michael
    Es handelt sich mal wieder um das "Array-Überwachungs-Problem". Wenn man etwas an einen ArrayController bindet, dann werden nur Änderungen am Array (hinzufügen, löschen, verschieben von Objekten) überwacht. Änderungen an den Objekten in dem Array sind aus Sicht der Cocoa-Bindings keine Änderung des Arrays! Das Problem hatten wir hier in letzter Zeit öfters besprochen.

    Michael


    Habe ich es mir doch gedacht... dann werde ich wohl wieder in einem Subclass von NSManagedObject dafür sorgen müssen, dass alle informiert werden...
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • Gelöst und zwar wie ich finde recht Elegant. In meinem NSManagedObject Subclass habe ich folgendes gemacht:

    Quellcode

    1. - (void)setActivated:(BOOL)value
    2. {
    3. NSLog(@"setActivated");
    4. [self willChangeValueForKey:@"activated"];
    5. [self setPrimitiveValue:[NSNumber numberWithBool:value] forKey:@"activated"];
    6. [[self managedObjectContext] refreshObject:self mergeChanges:YES];
    7. [self didChangeValueForKey:@"activated"];
    8. }


    Es wird einfach der ManagedObjectContext informiert...

    Das darf man doch - oder? Hab mal ein Beispielprojekt gemacht für die, die das selbe Problem haben... einfach kompilieren - ein paar Namen eingeben - auf den Button klicken - ein paar Namen deaktivieren und wieder button klicken...

    Wunderbar..
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • RE: Predicate auf NSArrayController anwenden und immer informiert bleiben

    Der *Array-Controller* observiert nur das Array. Eine Änderung einer Property eines Objektes im Array interessiert ihn nicht. Aber ein *einzelnes Feld* observiert etwa das Array und die *einzelne, angezeigte Property*. Das ist nichts Ungewöhnliches und erst einmal richtig.

    Da du hier einen Array-Controller hast und eine Abhängigkeit von einer einzelnen Property, geht *diese Kombination* eben in die Hose.

    Fame - Wege zum Ruhm, die mir so einfallen. (Ich werde das Problem demnächst auch haben.)
    a) Du observierst die einzelnen Objekte auf der Eigenschaft activated. Das kannst du in einer Subclass des Array-Controllers machen oder irgendwo in einem dezidierten Controller (Window-Controller etwa). Schlägt die Observierung ein, wird eben ein refresh durchgeführt.

    b) Du denkst dir eine neue Eigenschaft des haltenden Objektes aus, sagen wir activatedObjects. Im Setter des activate erzeugst du eine Nachricht (einfache Notification oder KVO-Nachricht für das haltende(!) Objekt). Da sowohl das haltende, wie das gehaltene Objekt sich im Model befinden, darfst du hier auch eine gewisse Abhängigkeit programmieren.
    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: Predicate auf NSArrayController anwenden und immer informiert bleiben

    Original von Tom9811
    Der *Array-Controller* observiert nur das Array. Eine Änderung einer Property eines Objektes im Array interessiert ihn nicht. Aber ein *einzelnes Feld* observiert etwa das Array und die *einzelne, angezeigte Property*. Das ist nichts Ungewöhnliches und erst einmal richtig.

    Da du hier einen Array-Controller hast und eine Abhängigkeit von einer einzelnen Property, geht *diese Kombination* eben in die Hose.

    Fame - Wege zum Ruhm, die mir so einfallen. (Ich werde das Problem demnächst auch haben.)
    a) Du observierst die einzelnen Objekte auf der Eigenschaft activated. Das kannst du in einer Subclass des Array-Controllers machen oder irgendwo in einem dezidierten Controller (Window-Controller etwa). Schlägt die Observierung ein, wird eben ein refresh durchgeführt.

    b) Du denkst dir eine neue Eigenschaft des haltenden Objektes aus, sagen wir activatedObjects. Im Setter des activate erzeugst du eine Nachricht (einfache Notification oder KVO-Nachricht für das haltende(!) Objekt). Da sowohl das haltende, wie das gehaltene Objekt sich im Model befinden, darfst du hier auch eine gewisse Abhängigkeit programmieren.


    Aber meine Lösung funktioniert doch auch prächtig... oder wieso hast du nochmals diese sehr lehrreichen Erklärungen ausgepackt? :)
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • RE: Predicate auf NSArrayController anwenden und immer informiert bleiben

    a) Weil mir nicht ganz klar war, was du mit "alle informiert" meinst.
    b) Weil viele Wege zum Ziel führen. (Alle nach Rom.)
    c) Weil ein Ausblick nie verkehrt ist.
    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"?