Si es así, ¿hay alguna diferencia clave que de otro modo no estaba presente al usar la observación de valor clave en Objective-C?
swift
key-value-observing
codeperson
fuente
fuente
.initial
. Para una solución ver aquí . Recomiendo ver los documentos de Apple . Se ha actualizado recientemente y cubre muchas notas importantes. Ver también la otra respuesta deRespuestas:
(Editado para agregar nueva información): considere si usar el marco Combinar puede ayudarlo a lograr lo que quería, en lugar de usar KVO
Si y no. KVO funciona en las subclases de NSObject como siempre lo ha hecho. No funciona para clases que no subclase NSObject. Swift no tiene (al menos actualmente) su propio sistema de observación nativo.
(Vea los comentarios sobre cómo exponer otras propiedades como ObjC para que KVO trabaje en ellas)
Consulte la documentación de Apple para ver un ejemplo completo.
fuente
dynamic
palabra clave en cualquier clase Swift para habilitar el soporte de KVO.dynamic
palabra clave va en la propiedad que desea que sea clave-valor-observable.dynamic
palabra clave se puede encontrar en la sección Uso de Swift con Cocoa y Objective-C de la Biblioteca para desarrolladores de Apple .dynamic
palabra clave para cualquier propiedad dentro de una clase que le gustaría cumplir con KVO (no ladynamic
palabra clave en la clase en sí). ¡Esto funcionó para mí!Puede usar KVO en Swift, pero solo para
dynamic
propiedades deNSObject
subclase. Considere que desea observar labar
propiedad de unaFoo
clase. En Swift 4, especifiquebar
comodynamic
propiedad en suNSObject
subclase:Luego puede registrarse para observar los cambios en la
bar
propiedad. En Swift 4 y Swift 3.2, esto se ha simplificado enormemente, como se describe en Uso de la observación de valores clave en Swift :Tenga en cuenta que en Swift 4, ahora tenemos un tipeo fuerte de las rutas de teclado utilizando el carácter de barra diagonal inversa (
\.bar
es la ruta de acceso de labar
propiedad del objeto que se está observando). Además, debido a que está utilizando el patrón de cierre de finalización, no tenemos que eliminar manualmente los observadores (cuando latoken
caída está fuera del alcance, el observador se elimina por nosotros) ni tenemos que preocuparnos de llamar a lasuper
implementación si la clave no partido. El cierre se llama solo cuando se invoca a este observador en particular. Para obtener más información, vea el video WWDC 2017, What's New in Foundation .En Swift 3, para observar esto, es un poco más complicado, pero muy similar a lo que se hace en Objective-C. Es decir, implementaría
observeValue(forKeyPath keyPath:, of object:, change:, context:)
qué (a) se asegura de que estemos tratando con nuestro contexto (y no con algo que nuestrasuper
instancia haya registrado para observar); y luego (b) manejarlo o pasarlo a lasuper
implementación, según sea necesario. Y asegúrese de retirarse como observador cuando sea apropiado. Por ejemplo, puede eliminar el observador cuando se desasigna:En Swift 3:
Tenga en cuenta que solo puede observar propiedades que se pueden representar en Objective-C. Por lo tanto, no puede observar genéricos,
struct
tipos Swiftenum
, tipos Swift , etc.Para una discusión sobre la implementación de Swift 2, vea mi respuesta original, a continuación.
El uso de la
dynamic
palabra clave para lograr KVO conNSObject
subclases se describe en la sección Observación de valores clave del capítulo Adopción de convenciones de diseño de cacao de la guía Uso rápido con cacao y Objetivo-C :[Tenga en cuenta que esta discusión de KVO se ha eliminado posteriormente de la guía Uso de Swift con Cocoa y Objective-C , que se ha adaptado para Swift 3, pero aún funciona como se describe en la parte superior de esta respuesta.]
Vale la pena señalar que Swift tiene su propio sistema de observación de propiedades nativas , pero eso es para una clase que especifica su propio código que se realizará al observar sus propias propiedades. KVO, por otro lado, está diseñado para registrarse para observar cambios en alguna propiedad dinámica de otra clase.
fuente
myContext
y cómo observa múltiples propiedades?context
puntero. Elcontext
puntero se proporciona al observador cuandoobserveValueForKeyPath:ofObject:change:context:
se invoca. Elcontext
puntero puede ser un puntero C o una referencia de objeto. Elcontext
puntero puede ser se utiliza como un identificador único para determinar el cambio que se está observando o para proporcionar otros datos al observador ".options
vacío, solo significa quechange
no incluirá el valor antiguo o nuevo (por ejemplo, puede obtener el nuevo valor usted mismo haciendo referencia al objeto mismo). Si solo especifica.new
y no.old
, significa quechange
incluirá solo el nuevo valor, pero no el valor anterior (por ejemplo, a menudo no le importa cuál era el valor anterior, sino solo el nuevo valor). Si necesitaobserveValueForKeyPath
pasarle el valor antiguo y el nuevo, especifique[.new, .old]
. Enoptions
pocas palabras, solo especifica lo que se incluye en elchange
diccionario.Tanto sí como no:
Sí , puede usar las mismas API antiguas de KVO en Swift para observar objetos Objective-C.
También puede observar
dynamic
propiedades de objetos Swift heredados deNSObject
.Pero ... No , no está fuertemente tipado como se podría esperar que sea el sistema de observación nativo Swift.
Usando Swift con cacao y Objective-C | Observación de valor clave
No , actualmente no existe un sistema de observación de valor incorporado para objetos Swift arbitrarios.
Sí , hay observadores de propiedades incorporados , que están fuertemente tipados.
Pero ... No, no son KVO, ya que solo permiten observar las propiedades propias de los objetos, no admiten observaciones anidadas ("rutas clave"), y debe implementarlas explícitamente.
El lenguaje de programación Swift | Observadores de propiedades
Sí , puede implementar la observación de valores explícitos, que se tipeará con fuerza, y permitirá agregar múltiples controladores de otros objetos, e incluso admitir anidamiento / "rutas clave".
Pero ... No , no será KVO ya que solo funcionará para propiedades que implemente como observables.
Puede encontrar una biblioteca para implementar dicho valor observando aquí:
Observable-Swift - KVO para Swift - Observación de valores y eventos
fuente
Un ejemplo podría ayudar un poco aquí. Si tengo una instancia
model
de claseModel
con atributosname
ystate
puedo observar esos atributos con:Los cambios en estas propiedades activarán una llamada a:
fuente
Si.
KVO requiere despacho dinámico, por lo que simplemente necesita agregar el
dynamic
modificador a un método, propiedad, subíndice o inicializador:dynamic var foo = 0
El
dynamic
modificador asegura que las referencias a la declaración se despacharán dinámicamente y se accederá a través de ellasobjc_msgSend
.fuente
Además de la respuesta de Rob. Esa clase debe heredar de
NSObject
, y tenemos 3 formas de activar el cambio de propiedadUsar
setValue(value: AnyObject?, forKey key: String)
desdeNSKeyValueCoding
Uso
willChangeValueForKey
ydidChangeValueForKey
deNSKeyValueObserving
Uso
dynamic
. Ver compatibilidad de tipo SwiftY la propiedad getter y setter se llama cuando se usa. Puede verificar cuando trabaja con KVO. Este es un ejemplo de propiedad calculada
fuente
Visión general
Es posible usar
Combine
sin usarNSObject
oObjective-C
Disponibilidad:
iOS 13.0+
,macOS 10.15+
,tvOS 13.0+
,watchOS 6.0+
,Mac Catalyst 13.0+
,Xcode 11.0+
Nota: Debe usarse solo con clases que no sean con tipos de valor.
Código:
Versión Swift: 5.1.2
Salida:
Referir:
fuente
Actualmente Swift no admite ningún mecanismo integrado para observar cambios de propiedad de objetos que no sean 'self', por lo que no, no admite KVO.
Sin embargo, KVO es una parte tan fundamental de Objective-C y Cocoa que parece bastante probable que se agregue en el futuro. La documentación actual parece implicar esto:
Usando Swift con cacao y Objective-C
fuente
Una cosa importante a mencionar es que después de actualizar su Xcode a 7 beta , puede recibir el siguiente mensaje: "El método no anula ningún método de su superclase" . Eso se debe a la opcionalidad de los argumentos. Asegúrese de que su controlador de observación tenga exactamente el siguiente aspecto:
fuente
Esto puede ser útil para algunas personas.
Había usado KVO de esta manera en Swift 3. Puede usar este código con pocos cambios.
fuente
¿Otro ejemplo para cualquiera que tenga un problema con tipos como Int? y CGFloat ?. Simplemente establece su clase como una subclase de NSObject y declara sus variables de la siguiente manera, por ejemplo:
fuente