Wenn ja, gibt es wesentliche Unterschiede, die bei Verwendung der Schlüsselwertbeobachtung in Objective-C nicht anderweitig vorhanden waren?
swift
key-value-observing
Codeperson
quelle
quelle
.initial
. Eine Lösung finden Sie hier . Ich empfehle dringend, Apple-Dokumente zu sehen . Es wurde kürzlich aktualisiert und enthält viele wichtige Hinweise. Siehe auch Robs andere AntwortAntworten:
(Bearbeitet, um neue Informationen hinzuzufügen): Überlegen Sie, ob die Verwendung des Kombinations-Frameworks Ihnen dabei helfen kann, das zu erreichen, was Sie wollten, anstatt KVO zu verwenden
Ja und nein. KVO arbeitet wie immer an NSObject-Unterklassen. Es funktioniert nicht für Klassen, die NSObject nicht unterordnen. Swift verfügt (zumindest derzeit) nicht über ein eigenes natives Beobachtungssystem.
(In den Kommentaren erfahren Sie, wie Sie andere Eigenschaften als ObjC verfügbar machen, damit KVO daran arbeitet.)
Ein vollständiges Beispiel finden Sie in der Apple-Dokumentation .
quelle
dynamic
Schlüsselwort für jede Swift-Klasse verwenden, um die KVO-Unterstützung zu aktivieren.dynamic
Schlüsselwort auf die Eigenschaft, die Sie als Schlüsselwert beobachtbar machen möchten.dynamic
Schlüsselwort finden Sie im Abschnitt Verwenden von Swift mit Kakao und Objective-C der Apple Developer Library .dynamic
Schlüsselwort für alle Eigenschaften innerhalb einer Klasse, die Sie KVO-kompatibel sein möchten (nicht dasdynamic
Schlüsselwort für die Klasse selbst). Das hat bei mir funktioniert!Sie können KVO in Swift verwenden, jedoch nur für
dynamic
Eigenschaften derNSObject
Unterklasse. Bedenken Sie, dass Sie diebar
Eigenschaft einerFoo
Klasse beobachten möchten. Geben Sie in Swift 4bar
alsdynamic
Eigenschaft in IhrerNSObject
Unterklasse Folgendes an:Sie können sich dann registrieren, um Änderungen an der
bar
Eigenschaft zu beobachten . In Swift 4 und Swift 3.2 wurde dies erheblich vereinfacht, wie unter Verwenden der Schlüsselwertbeobachtung in Swift beschrieben :Beachten Sie, dass in Swift 4 jetzt Schlüsselpfade mit dem Backslash-Zeichen stark eingegeben werden (dies
\.bar
ist der Schlüsselpfad für diebar
Eigenschaft des beobachteten Objekts). Da das Abschlussmuster für die Fertigstellung verwendet wird, müssen wir Beobachter nicht manuell entfernen (wenn dertoken
Gültigkeitsbereich ausfällt, wird der Beobachter für uns entfernt), und wir müssen uns auch nicht darum kümmern, diesuper
Implementierung aufzurufen , wenn der Schlüssel dies nicht tut Spiel. Die Schließung wird nur aufgerufen, wenn dieser bestimmte Beobachter aufgerufen wird. Weitere Informationen finden Sie im WWDC 2017-Video " Was ist neu in Foundation?" .Um dies zu beobachten, ist es in Swift 3 etwas komplizierter, aber sehr ähnlich zu dem, was man in Objective-C macht. Sie würden nämlich implementieren,
observeValue(forKeyPath keyPath:, of object:, change:, context:)
was (a) sicherstellt, dass wir uns mit unserem Kontext befassen (und nicht mit etwas, das unseresuper
Instanz zur Beobachtung registriert hat); und dann (b) entweder damit umgehen oder es nachsuper
Bedarf an die Implementierung weitergeben. Und stellen Sie sicher, dass Sie sich gegebenenfalls als Beobachter entfernen. Beispielsweise können Sie den Beobachter entfernen, wenn er freigegeben wird:In Swift 3:
Beachten Sie, dass Sie nur Eigenschaften beobachten können, die in Objective-C dargestellt werden können. Daher können Sie keine Generika, Swift-
struct
Typen, Swift-enum
Typen usw. beobachten.Eine Diskussion der Swift 2-Implementierung finden Sie in meiner ursprünglichen Antwort unten.
Unter Verwendung des
dynamic
Keyword - KVO zu erreichen mitNSObject
Subklassen in dem beschriebenen Schlüsselwert Observing Abschnitt der Annahme Cocoa Designs Konventionen Kapitel der Verwendung von Swift mit Cocoa und Objective-C Anleitung:[Beachten Sie, dass diese KVO-Diskussion später aus dem Handbuch „ Swift mit Kakao und Objective-C verwenden“ entfernt wurde, das für Swift 3 angepasst wurde, aber weiterhin wie oben in dieser Antwort beschrieben funktioniert.]
Es ist erwähnenswert, dass Swift über ein eigenes natives Eigenschaftsbeobachtungssystem verfügt, dies gilt jedoch für eine Klasse, die ihren eigenen Code angibt, der bei Beobachtung ihrer eigenen Eigenschaften ausgeführt wird. KVO hingegen ist so konzipiert, dass es sich registriert, um Änderungen an einer dynamischen Eigenschaft einer anderen Klasse zu beobachten.
quelle
myContext
und wie beobachten Sie mehrere Eigenschaften?context
Zeiger bereitstellen . Dercontext
Zeiger wird dem Beobachter beimobserveValueForKeyPath:ofObject:change:context:
Aufrufen bereitgestellt . Dercontext
Zeiger kann ein C-Zeiger oder eine Objektreferenz sein. Dercontext
Zeiger kann sein wird als eindeutige Kennung verwendet, um die beobachtete Änderung zu bestimmen oder um dem Beobachter einige andere Daten zur Verfügung zu stellen. "options
leer lassen, bedeutet dies nur, dass derchange
alte oder neue Wert nicht enthalten ist (z. B. erhalten Sie den neuen Wert möglicherweise selbst, indem Sie auf das Objekt selbst verweisen). Wenn Sie nur angeben.new
und nicht.old
, bedeutet dies, dasschange
nur der neue Wert, nicht jedoch der alte Wert enthalten ist (z. B. ist es Ihnen oft egal, was der alte Wert war, sondern nur der neue Wert). Wenn SieobserveValueForKeyPath
sowohl den alten als auch den neuen Wert übergeben müssen, geben Sie an[.new, .old]
. Unter dem Strich wirdoptions
nur angegeben, was imchange
Wörterbuch enthalten ist.Ja und Nein:
Ja , Sie können dieselben alten KVO-APIs in Swift verwenden, um Objective-C-Objekte zu beobachten.
Sie können auch
dynamic
Eigenschaften von Swift-Objekten beobachten, von denen geerbt wirdNSObject
.Aber ... Nein, es ist nicht stark typisiert, wie man es von einem nativen Swift-Beobachtungssystem erwarten kann.
Verwenden von Swift mit Kakao und Objective-C | Schlüsselwert beobachten
Nein , derzeit gibt es kein eingebautes Wertebeobachtungssystem für beliebige Swift-Objekte.
Ja , es gibt eingebaute Property Observers , die stark typisiert sind.
Aber ... Nein, sie sind keine KVO, da sie nur die Beobachtung von Objekteigenschaften ermöglichen, keine verschachtelten Beobachtungen ("Schlüsselpfade") unterstützen und Sie diese explizit implementieren müssen.
Die schnelle Programmiersprache | Immobilienbeobachter
Ja , Sie können eine explizite Wertebeobachtung implementieren, die stark typisiert wird, das Hinzufügen mehrerer Handler aus anderen Objekten ermöglichen und sogar Verschachtelungs- / "Schlüsselpfade" unterstützen.
Aber ... Nein, es wird kein KVO sein, da es nur für Eigenschaften funktioniert, die Sie als beobachtbar implementieren.
Eine Bibliothek zur Implementierung einer solchen Wertebeobachtung finden Sie hier:
Observable-Swift - KVO für Swift - Value Observing and Events
quelle
Ein Beispiel könnte hier ein wenig helfen. Wenn ich eine
model
KlasseninstanzModel
mit Attributen habename
undstate
diese Attribute beobachten kann mit:Änderungen an diesen Eigenschaften lösen einen Aufruf aus:
quelle
Ja.
KVO erfordert einen dynamischen Versand, daher müssen Sie den
dynamic
Modifikator lediglich einer Methode, Eigenschaft, einem Index oder einem Initialisierer hinzufügen :dynamic var foo = 0
Der
dynamic
Modifikator stellt sicher, dass Verweise auf die Deklaration dynamisch gesendet und über abgerufen werdenobjc_msgSend
.quelle
Neben Robs Antwort. Diese Klasse muss von erben
NSObject
, und wir haben drei Möglichkeiten, um eine Eigenschaftsänderung auszulösenVerwenden Sie
setValue(value: AnyObject?, forKey key: String)
vonNSKeyValueCoding
Verwenden Sie
willChangeValueForKey
unddidChangeValueForKey
vonNSKeyValueObserving
Verwenden Sie
dynamic
. Siehe Swift-TypkompatibilitätUnd Property Getter und Setter werden bei Verwendung aufgerufen. Sie können überprüfen, ob Sie mit KVO arbeiten. Dies ist ein Beispiel für eine berechnete Eigenschaft
quelle
Überblick
Es ist möglich,
Combine
ohneNSObject
oder zu verwendenObjective-C
Verfügbarkeit:
iOS 13.0+
,macOS 10.15+
,tvOS 13.0+
,watchOS 6.0+
,Mac Catalyst 13.0+
,Xcode 11.0+
Hinweis: Muss nur mit Klassen verwendet werden, nicht mit Werttypen.
Code:
Schnelle Version: 5.1.2
Ausgabe:
Verweisen:
quelle
Derzeit unterstützt Swift keinen eingebauten Mechanismus zum Beobachten von Eigenschaftsänderungen von anderen Objekten als 'self'. Nein, KVO wird nicht unterstützt.
KVO ist jedoch ein so grundlegender Bestandteil von Objective-C und Cocoa, dass es sehr wahrscheinlich ist, dass es in Zukunft hinzugefügt wird. Die aktuelle Dokumentation scheint dies zu implizieren:
Verwenden von Swift mit Cocoa und Objective-C
quelle
Eine wichtige Sache zu erwähnen ist, dass nach dem Aktualisieren Ihres Xcodes auf 7 Beta möglicherweise die folgende Meldung angezeigt wird: "Methode überschreibt keine Methode aus ihrer Oberklasse" . Das liegt an der Optionalität der Argumente. Stellen Sie sicher, dass Ihr Beobachtungshandler genau wie folgt aussieht:
quelle
Dies kann sich für wenige Menschen als hilfreich erweisen -
Ich hatte KVO in Swift 3 auf diese Weise verwendet. Sie können diesen Code mit wenigen Änderungen verwenden.
quelle
Ein weiteres Beispiel für alle, die auf ein Problem mit Typen wie Int? und CGFloat?. Sie legen Ihre Klasse einfach als Unterklasse von NSObject fest und deklarieren Ihre Variablen wie folgt, z.
quelle