¿Es posible agregar propiedades a un objeto Objective C en tiempo de ejecución?¿Cómo puedo agregar propiedades a un objeto en tiempo de ejecución?
Respuesta
Es posible añadir propiedades formales a través de una clase class_addProperty()
:
BOOL class_addProperty(Class cls,
const char *name,
const objc_property_attribute_t *attributes,
unsigned int attributeCount)
Los primeros dos parámetros son fáciles de entender. El tercer parámetro es una matriz de atributos de propiedad, y cada atributo de propiedad es un par nombre-valor que sigue Objective-C type encodings para declared properties. Tenga en cuenta que la documentación aún menciona la cadena separada por comas para la codificación de los atributos de propiedad. Cada segmento en la cadena separada por comas está representado por una instancia objc_property_attribute_t
. Además, objc_property_attribute_t
acepta nombres de clase además de la codificación de tipo genérica @
de id
.
Aquí está un primer borrador de un programa que agrega dinámicamente una propiedad llamada name
a una clase que ya tiene una variable de instancia llamada _privateName
:
#include <objc/runtime.h>
#import <Foundation/Foundation.h>
@interface SomeClass : NSObject {
NSString *_privateName;
}
@end
@implementation SomeClass
- (id)init {
self = [super init];
if (self) _privateName = @"Steve";
return self;
}
@end
NSString *nameGetter(id self, SEL _cmd) {
Ivar ivar = class_getInstanceVariable([SomeClass class], "_privateName");
return object_getIvar(self, ivar);
}
void nameSetter(id self, SEL _cmd, NSString *newName) {
Ivar ivar = class_getInstanceVariable([SomeClass class], "_privateName");
id oldName = object_getIvar(self, ivar);
if (oldName != newName) object_setIvar(self, ivar, [newName copy]);
}
int main(void) {
@autoreleasepool {
objc_property_attribute_t type = { "T", "@\"NSString\"" };
objc_property_attribute_t ownership = { "C", "" }; // C = copy
objc_property_attribute_t backingivar = { "V", "_privateName" };
objc_property_attribute_t attrs[] = { type, ownership, backingivar };
class_addProperty([SomeClass class], "name", attrs, 3);
class_addMethod([SomeClass class], @selector(name), (IMP)nameGetter, "@@:");
class_addMethod([SomeClass class], @selector(setName:), (IMP)nameSetter, "[email protected]:@");
id o = [SomeClass new];
NSLog(@"%@", [o name]);
[o setName:@"Jobs"];
NSLog(@"%@", [o name]);
}
}
Su (recortada) de salida:
Steve
Jobs
Los métodos getter y setter deberían escribirse con más cuidado, pero esto debería ser suficiente como un ejemplo de cómo agregar dinámicamente una propiedad formal en tiempo de ejecución.
class_addProperty devuelve true, pero class_getInstanceVariable siempre devuelve nil. Intenté poner el nombre de la propiedad en lugar del nombre ivar, pero todavía no tuve suerte. ¿Alguna idea de lo que podría ser el problema? – Mercurial
@Bavarious, ¿cómo engañaste al compilador? Quiero decir que [o name] da como resultado el error de compilación 'No se conoce ningún método de instancia para el selector' nombre ''. –
@HiteshSavaliya hace mucho tiempo (antes de ARC) esto era solo posible. hoy en día tendrías que al menos declarar el selector '-name'. – Michael
@properties - no (es decir, utilizando la sintaxis de punto, etc.). Pero puede agregar almacenamiento mediante el uso de objetos asociados: How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?.
Si se echa un vistazo a NSKeyValueCoding
protocolo, documentado here, se puede ver que hay un mensaje llamado:
- (id)valueForUndefinedKey:(NSString *)key
debe reemplazar ese método para proporcionar el resultado de la medida para la propiedad no definida especificada. Por supuesto, esto supone que su clase utiliza el protocolo correspondiente.
Este tipo de enfoque se usa comúnmente para proporcionar un comportamiento desconocido a las clases (por ejemplo, un selector que no existe).
- 1. Agregar miembros a un objeto dinámico en tiempo de ejecución
- 2. ¿Cómo agregar margen a un botón en tiempo de ejecución?
- 3. C#: ¿Cómo agregar atributos a un objeto en tiempo de ejecución?
- 4. Loop a través de todas las propiedades de objeto en tiempo de ejecución
- 5. Java - Propiedades: ¿Agregar nuevas claves al archivo de propiedades en tiempo de ejecución?
- 6. Agregar atributos attr adicionales en tiempo de ejecución a un objeto activerecord
- 7. ¿Cómo se define un objeto C# en tiempo de ejecución?
- 8. Agregar imagen en tiempo de ejecución
- 9. Cómo agregar un UIButton en tiempo de ejecución
- 10. ¿Cómo agregar propiedades al objeto anónimo dinámicamente?
- 11. Agregar elementos a RibbonDropDown en tiempo de ejecución
- 12. ¿Cómo puedo agregar métodos a una clase en tiempo de ejecución en Smalltalk?
- 13. Cómo modificar PropertyGrid en tiempo de ejecución (agregar/eliminar propiedades y tipos dinámicos/enumeraciones)
- 14. Agregar archivos a Java classpath en el tiempo de ejecución
- 15. Cómo agrego componentes a un JPanel en tiempo de ejecución
- 16. Agregar dinámicamente miembros a un objeto dinámico
- 17. Agregando propiedades desconocidas (en tiempo de diseño) a un ExpandoObject
- 18. Ignorar algunas propiedades en tiempo de ejecución al usar DataContractSerializer
- 19. Cambie las propiedades de log4j en tiempo de ejecución
- 20. ¿Cómo agregar un control de botón a una vista xml de Android en tiempo de ejecución?
- 21. Tamaño de un objeto en tiempo de ejecución
- 22. ¿Cómo puedo cargar un módulo Perl en tiempo de ejecución?
- 23. ¿Puedo agregar propiedades arbitrarias a objetos DOM?
- 24. Agregar tiempo al objeto POSIXct en R
- 25. Decidir qué propiedades se serializan en el tiempo de ejecución
- 26. Marco de entidad: Agregar propiedades/entidades durante el tiempo de ejecución
- 27. ¿Cómo puedo agregar un elemento de la barra de acciones durante el tiempo de ejecución
- 28. ¿Cómo usar layoutinflator para agregar vistas en tiempo de ejecución?
- 29. Agregar funciones en gdb en tiempo de ejecución
- 30. ¿Se puede forzar a un objeto java a implementar una interfaz en tiempo de ejecución?
si es compatible con el protocolo KVC - es posible – Nekto
¿A qué se refiere exactamente por propiedades? Objective-C declaró propiedades? –
Quiero decir @property – cfischer