È possibile aggiungere proprietà a un oggetto Objective C in fase di runtime?Come posso aggiungere proprietà a un oggetto in fase di runtime?
risposta
E 'possibile aggiungere proprietà formali a una classe tramite class_addProperty()
:
BOOL class_addProperty(Class cls,
const char *name,
const objc_property_attribute_t *attributes,
unsigned int attributeCount)
I primi due parametri sono auto-esplicativi. Il terzo parametro è un array di attributi di proprietà e ogni attributo di proprietà è una coppia nome-valore che segue Objective-C type encodings per declared properties. Si noti che la documentazione menziona ancora la stringa separata da virgola per la codifica degli attributi di proprietà. Ogni segmento nella stringa separata da virgola è rappresentato da un'istanza objc_property_attribute_t
. Inoltre, objc_property_attribute_t
accetta nomi di classi oltre alla codifica generica di tipo @
di id
.
Ecco una prima bozza di un programma che aggiunge dinamicamente una proprietà chiamata name
ad una classe che ha già una variabile di istanza denominata _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]);
}
}
sua (tagliati) Uscita:
Steve
Jobs
I metodi getter e setter dovrebbero essere scritti con più attenzione, ma questo dovrebbe essere sufficiente come esempio di come aggiungere dinamicamente una proprietà formale in fase di runtime.
class_addProperty restituisce true, ma class_getInstanceVariable restituisce sempre nil. Ho provato a mettere il nome della proprietà invece del nome di ivar, ma ancora senza fortuna. Qualche idea su quale potrebbe essere il problema? – Mercurial
@Bavarious, come hai ingannato il compilatore? Voglio dire [o nome] risultati in errore di compilazione 'Nessun metodo di istanza noto per il selettore' nome ''. –
@HiteshSavaliya molto tempo fa (prima di ARC) questo era solo possibile. al giorno d'oggi dovresti almeno dichiarare il selettore '-name'. – Michael
@proprietà - no (cioè utilizzando la sintassi del punto ecc.). Ma puoi aggiungere spazio di archiviazione usando gli oggetti associati: How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?.
Se si dà un'occhiata a NSKeyValueCoding
protocollo, documentato here, si può vedere che c'è un messaggio chiamato:
- (id)valueForUndefinedKey:(NSString *)key
Si dovrebbe ignorare che il metodo per fornire il risultato personalizzato per la proprietà non definita specificata. Ovviamente questo presuppone che la tua classe utilizzi il protocollo corrispondente.
Questo tipo di approccio viene comunemente utilizzato per fornire un comportamento sconosciuto alle classi (ad esempio un selettore che non esiste).
- 1. Riesci a rendere un oggetto serializzabile in fase di runtime?
- 2. Come aggiungere una vista dinamica a un oggetto ListView in fase di runtime?
- 3. In Maven, come posso creare dinamicamente un valore di proprietà in fase di runtime?
- 4. Come posso creare una proprietà multi-selezione dinamica su un oggetto IEnumerable <T> in fase di runtime?
- 5. Come posso caricare un modulo Perl in fase di runtime?
- 6. Come aggiungere un controllo pulsante a una vista xml android in fase di runtime?
- 7. posso specificare un maven project.artifactId in fase di runtime?
- 8. Come aggiungere elementi a un gtk.ComboBox creato tramite glade in fase di runtime?
- 9. Posso disattivare facoltativamente l'attributo JsonIgnore in fase di runtime?
- 10. Proprietà dinamiche Objective-C in fase di runtime?
- 11. Come posso disabilitare le virgolette PHP in fase di runtime?
- 12. Widget Android: come aggiungere viste a RemoteViews in fase di runtime
- 13. Come aggiungere componenti a un JPanel in fase di esecuzione
- 14. C#: come aggiungere un attributo a un oggetto in fase di esecuzione?
- 15. Come posso fare riferimento a un controllo il cui nome è determinato in fase di runtime?
- 16. Come posso assegnare una proprietà a un oggetto jQuery?
- 17. Come viene interpretato ed eseguito XAML in fase di runtime?
- 18. Come posso aggiungere un oggetto a un ListBox?
- 19. Come aggiungere margine a un pulsante in fase di esecuzione?
- 20. Come posso creare una selezione dinamica su un oggetto IEnumerable <T> in fase di runtime?
- 21. Come aggiungere un attributo a una proprietà in fase di esecuzione
- 22. Objective-C: come modificare la classe di un oggetto in fase di runtime?
- 23. Modificare la locale in fase di runtime?
- 24. Aggiunta di membri a un oggetto dinamico in fase di esecuzione
- 25. Come si accede a un metodo da un jar esterno in fase di runtime?
- 26. Come modificare un MOMP POM in fase di runtime?
- 27. C# Reflection: è possibile trovare un'istanza di un oggetto in fase di runtime?
- 28. Come aggiungere gli elementi a un oggetto PanoramaItem in WP7
- 29. È possibile aggiungere una directory al percorso della classe in fase di runtime?
- 30. Caricamento XAML in fase di runtime?
se è conforme al protocollo KVC - è possibile – Nekto
Che cosa intendete esattamente per proprietà? Proprietà dichiarate Objective-C? –
Intendo @property – cfischer