Es gibt zwei integrierte Möglichkeiten zur Beobachtung in Cocoa: Schlüsselwertbeobachtung und Benachrichtigungen. In keinem System müssen Sie eine Sammlung von Beobachtern selbst pflegen oder benachrichtigen; Das Framework wird das für Sie erledigen.
Mit der Schlüsselwertbeobachtung (KVO) können Sie eine Eigenschaft eines Objekts beobachten - einschließlich einer Eigenschaft, die eine Auflistung darstellt - und über Änderungen an dieser Eigenschaft benachrichtigt werden. Sie müssen nur das Objekt -addObserver:forKeyPath:options:context:
senden, das das Objekt, für das Sie Updates erhalten möchten, übergibt, den Schlüsselpfad der Eigenschaft (relativ zum Empfänger), für den Sie Updates erhalten möchten, und die Arten von Updates, die Sie erhalten möchten. (Es gibt ähnliche Methoden, die Sie verwenden können, wenn Sie eine Eigenschaft beobachten möchten, die eine Auflistung darstellt.)
Benachrichtigungen sind älter und schwerer. Sie registrieren sich mit einem NSNotificationCenter
- in der Regel das Standard-Center - ein Objekt und Selektor-Paar, um eine Benachrichtigung zu geben, wenn ein Ereignis auftritt. Das Benachrichtigungsobjekt selbst kann beliebige Daten über seine userInfo
-Eigenschaft enthalten. Sie können festlegen, dass alle Benachrichtigungen eines bestimmten Namens statt der für ein bestimmtes Objekt geltenden Benachrichtigungen beobachtet werden.
Welche sollten Sie in einem bestimmten Fall verwenden? Wenn Sie Änderungen an einer bestimmten Eigenschaft eines bestimmten Objekts vornehmen möchten, verwenden Sie im Allgemeinen die Schlüsselwertbeobachtung. Dafür wurde es entwickelt und es ist absichtlich leicht. (Neben anderen Verwendungen ist dies die Grundlage, auf der Cocoa Bindings basieren.) Wenn Sie sich für eine Statusänderung interessieren, die nicht durch eine Eigenschaft dargestellt wird, sind Benachrichtigungen sinnvoller.
Um beispielsweise synchron zu bleiben, wenn der Benutzer den Namen eines Modellobjekts ändert, würde ich KVO verwenden. Um zu wissen, wann ein gesamtes Objektdiagramm gespeichert wurde, würde ich Benachrichtigungen verwenden.
Große Antwort - aber wie entfernen Sie mit dem KVO-Ansatz einen Beobachter, der sich bei vielen Objekten registriert hat? Ich dachte (fälschlicherweise), dass KVO Benachrichtigungen unter der Haube verwendet hat - aber ich denke nicht, dass es funktioniert. Nach der Verwendung von addObserver: X forKeyPath: ..., wenn Sie später versuchen: [[NSNotificationCenter defaultCenter] removeObserver: X] funktioniert das nicht? Es scheint zu implizieren, dass Sie eine separate Liste aller Objekte, die X beobachtet, behalten müssen, damit Sie die Beobachtung entfernen können. Oder fehlt mir etwas? – TimM
@TimM: Sie würden die entsprechende Methode für das beobachtete Objekt aufrufen. Zum Beispiel: '[self removeObserver: theObserver fürKeyPath: @" someProperty "];' – FreeAsInBeer
Neu in OS X 10.7 Lion und iOS 5.0 gibt es eine Methode -removeObserver: forKeyPath: context: an die Sie den gleichen Kontext übergeben können, den Sie wann übergeben haben Hinzufügen des Beobachters. Sie sollten das tun, wann immer es möglich ist, falls mehrere Objekte denselben Schlüsselpfad beobachten. –