Schlüsselwert - Beobachten einer To-Viele-Beziehung in Cocoa

8

Ich versuche, Schlüssel-Wert-Beobachtung für ein NSMutableArray arbeiten zu lassen. Unten ist die .h-Datei für MyObservee, die beobachtete Klasse:

%Vor%

Die Klasse MyObserver implementiert observeValueForKeyPath: ofObject: change: context :. Hier ist, wie ich den Beobachter hinzufügen:

%Vor%

Wie kommt es, dass die addObject: -Nachricht nicht als Änderung des someArray-Schlüsselpfades ausgelöst wird? Ich habe das Gefühl, dass es etwas gibt, was ich hier nicht vollständig verstehe.

    
Sam Lee 25.01.2009, 05:36
quelle

3 Antworten

12

Sie müssen die indizierten Array-Zugriffsmethoden wie in KVC definiert implementieren Programmierhandbuch . Dann müssen Sie diese Accessoren verwenden, um auf das Array zuzugreifen, und die KVO-Triggerung funktioniert. Sie können auch -mutableArrayValueForKey: und verwende dieses Array um addObject: und so und es wird wiederum die Accessor-Methoden aufrufen und die KVO-Triggerung wird ebenfalls auftreten. Es gibt auch Set-Accessoren für die Verwendung in NSSets, siehe hier und hier .

Beispiel:

%Vor%     
robottobor 25.01.2009, 06:43
quelle
4

Leider sind die NSArray-Klassen Anmerkung KVO-konform. Sie sind KVC-konform, aber Sie können sie nicht direkt beobachten, wie Sie es hier versuchen. Der einfachste Weg, diese Funktionalität zu erhalten, wäre die Verwendung eines NSArrayControllers. Der NSArray-Controller ist KVO-kompatibel und benachrichtigt Sie, wenn Elemente hinzugefügt oder entfernt werden. In Ihrem Beispiel würde Ihr Beobachter benachrichtigt werden, wenn Sie das Array selbst geändert haben . Zum Beispiel, wenn Sie so etwas getan haben:

%Vor%

Das ist wahrscheinlich nicht das, was Sie überhaupt wollten :) Nebenbei bemerkt, NSDictionary ist tatsächlich KVO-kompatibel, so dass Sie das verwenden könnten, wenn Sie dies wünschen. Oder Sie könnten eine Wrapper-Unterklasse von NSMutableArray schreiben, die nur ein echtes veränderbares Array als Backing-Store erstellt, aber nur alle Nachrichten an sie weiterleitet außer addObject und removeObject , die Sie überschreiben könnten, um Benachrichtigungen auszulösen.

    
Jason Coco 25.01.2009 06:17
quelle
3

Warum geben Sie Ihr privates Array an ein anderes Objekt weiter? Es ist nicht so privat, wenn Sie andere Objekte damit umgehen lassen.

Wie s-bug sagte, sollten Sie die Accessoren implementieren und mutableArrayValueForKey: verwenden, um die Eigenschaft zu mutieren. Ich füge hinzu, dass das private Array überhaupt nicht verfügbar machen sollte - Ihre someArray -Methode sollte eine unveränderliche Kopie des Arrays zurückgeben.

Außerdem rufe ich deine Aufmerksamkeit auf Jason Cocos Kommentar zu s-bugs Antwort hin. Um ihn zu paraphrasieren, sollten Sie wahrscheinlich einen NSArrayController als zusätzlichen Schritt der Trennung zwischen myObservee und myObserver verwenden. Dies ist ein sehr guter Vorschlag, und wenn Sie keinen bestimmten Grund haben, die Eigenschaft direkt zu beobachten, sollten Sie es nehmen. (Zu den Vorteilen gehört, dass Sie Bindungen verwenden können, um Ansichten mit dem neuen Array-Controller zu verbinden.)

    
Peter Hosey 25.01.2009 10:22
quelle