iphone - una - valor bases de datos
¿Cómo se puede saber si existe una clave para un objeto mediante la codificación de clave-valor? (3)
No hay manera, en general, de determinar si un objeto tiene un valor para una clave determinada. Una instancia puede decidir devolver un valor para una clave no definida de otro modo a partir de su método -valueForUndefinedKey:
. O puede permitir que la implementación predeterminada arroje una excepción. Los objetos modernos Objective-C (2.0) a menudo declaran propiedades relevantes en su API pública. Para estos objetos, puede usar class_copyPropertyList
o protocol_copyPropertyList
del class_copyPropertyList
de ejecución de Objective-C para obtener una lista de las propiedades disponibles. También puede emular la lista de búsqueda de KVC, probando mediante repondsToSelector:
si la instancia responde a un método getter apropiado. Finalmente, puede usar el class_copyIvarList
la ejecución para verificar los ivars para un ivar apropiado. Esto es mucho trabajo que no deberías estar haciendo . No garantiza que sepa si una instancia de objeto generará una excepción cuando se le envíe un valor de valueForKey:
mensaje e indica un problema mayor ...
Si tiene una colección de objetos que todos deben proporcionar un valor para una clave determinada, pero otros no, tiene un problema de diseño. Debe definir una interfaz apropiada (un @protocol
en Objective-C) que declare las propiedades necesarias. Luego puede probar la conformidad con este protocolo, o hacer uso del compilador para verificar el tipo de tiempo en tiempo de compilación para asegurarse de que la instancia se ajuste al protocolo (si está pasando por instancias únicas).
Me gustaría probar si un objeto tiene una @ propiedad escribible en el SDK de iPhone.
Una forma posible de hacerlo es comprobar el método -valueForKey: ¡pero parece bastante poco elegante!
Ejemplo:
@try {
id *value = [instance valueForKey:@"myProperty"];
}
@catch (NSException * e) {
// Key did not exist
}
¿Hay una mejor manera de hacer esto?
Si está creando el objeto que se está valueForUndefinedKey:
, puede reemplazar valueForUndefinedKey:
y setValue:forUndefinedKey
para hacer algo más útil que generar una excepción.
Si, por otro lado, intentas introspectir objetos que no conoces en tiempo de ejecución, deberás utilizar los métodos de tiempo de ejecución para hacerlo. Puede usar el tiempo de ejecución class_copyPropertyList
-c mismo y llamar class_copyPropertyList
o protocol_copyPropertyList
y tratar con eso, o usar Foundation y llamar respondsToSelector
al objeto para el getter / setters de KVC para una propiedad dada, por ejemplo, para un foo
propiedad al que llamaría algo así como [someObject respondsToSelector:NSSelectorFromString(@"foo")];
.
Siguiendo con la respuesta de @Jason Coco.
Aquí está mi oferta sobre cómo verificar específicamente la existencia de selectores "establecidos" de la propiedad que está tratando de establecer.
Esto es pura suciedad, pero funciona y me he encontrado utilizándolo. Has sido advertido..
NS_INLINE SEL _Nonnull IBPropertySetSelectorForPropertyName(NSString*_Nonnull propertyName)
{
NSString* firstLetter = [propertyName substringToIndex:1];
propertyName = [propertyName substringFromIndex:1];
propertyName = [[NSString alloc] initWithFormat:@"set%@%@:",firstLetter.capitalizedString,propertyName];
return NSSelectorFromString(propertyName);
}
Uso:
Rápidamente: agregue el fragmento de código a su encabezado de puente y luego:
let key = "someKey"
let sel = IBPropertySetSelectorForPropertyName(key)
if SOMETHING.responds(to: sel) {SOMETHING.setValue(value, forKeyPath: key)}