objective c - propiedades - ¿Cómo encuentro todas las claves de propiedad de un objeto Objective-C compatible con KVC?
propiedades javascript (6)
¿Hay algún método que devuelva todas las claves de un objeto que cumpla con el protocolo NSKeyValueCoding?
Algo a lo largo de las líneas de [object getPropertyKeys]
que devolvería una NSArray de objetos NSString. Funcionaría para cualquier objeto compatible con KVC. ¿Existe tal método? No he encontrado nada en la búsqueda de los documentos de Apple hasta ahora.
Gracias, G.
Entorno: Xcode7.2, iOS9.2
Uso el siguiente fragmento de código para obtener los nombres de propiedad de una clase específica, funciona bien:
importar "objc / runtime.h"
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([SNBankBean class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSLog(@"the property name is %@",propertyName);
if ([propertyName isEqualToString:bank_name]) {
self.isBankExisted=YES;
}
}
}
free(properties);
Necesita una función getPropertyType. Vea este post: Obtenga una lista de atributos de objeto en Objective-C
No existe un método como el sistema KVO que no requiere que los objetos / clases registren para qué propiedades son compatibles con KVO. Cualquier clave podría ser compatible con KVO, la única forma de saber es a partir de la documentación del autor.
Y, por supuesto, no hay garantía de que una @property
sea compatible con KVO; es muy posible escribir una propiedad que no lo hace (y puede ser necesario a veces). Por lo tanto, obtener una lista de las @property
s de una clase y luego asumir que son compatibles con KVO sería una opción peligrosa en mi opinión.
Para los Encodable
Swift, puede obtener esta funcionalidad utilizando la funcionalidad Encodable
. Explicaré cómo:
Conforme su objeto al protocolo
Encodable
class ExampleObj: NSObject, Encodable { var prop1: String = "" var prop2: String = "" }
Crear una extensión para
Encodable
para proporcionar funcionalidad detoDictionary
.public func toDictionary() -> [String: AnyObject]? { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted guard let data = try? encoder.encode(self), let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let jsonDict = json as? [String: AnyObject] else { return nil } return jsonDict }
Llame a
toDictionary
en su instancia de objeto y acceda a la propiedad dekeys
.let exampleObj = ExampleObj() exampleObj.toDictionary()?.keys
Voila! Acceda a sus propiedades como tal:
for k in exampleObj!.keys { print(k) } // Prints "prop1" // Prints "prop2"
Utilice class_getPropertyList . Eso te dirá todas las @properties
del objeto.
No necesariamente listará todas las propiedades compatibles con KVC, porque cualquier método que no tome argumentos y devuelva un valor es un captador válido que cumple con KVC. No hay una forma 100% confiable para que el tiempo de ejecución sepa cuáles se comportan como propiedades (por ejemplo, -[NSString length]
) y cuáles se comportan como comandos (por ejemplo, -[NSFileHandle readDataToEndOfFile]
).
Debería declarar sus propiedades compatibles con KVC como @properties
todos modos, por lo que esto no debería ser un problema demasiado grande.
#import "objc/runtime.h"
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
}
}
free(properties);