2010-03-20 20 views
18

Decir que tengo mi claseDe todos modos para obtener cadena de nombre de variable?

@interface Person : NSObject { NSString *name; } 

que necesito para obtener el nombre de NSString de dentro de mi clase

Person *person = [[Person alloc] init]; 
NSLog(@"Name of variable %s\n", _NameofVariable_(person->name)); 

Gracias por las respuestas, aquí está la solución que se me ocurrió a partir de las respuestas

//returns nil if property is not found 
-(NSString *)propertyName:(id)property { 
    unsigned int numIvars = 0; 
    NSString *key=nil; 
    Ivar * ivars = class_copyIvarList([self class], &numIvars); 
    for(int i = 0; i < numIvars; i++) { 
     Ivar thisIvar = ivars[i]; 
     if ((object_getIvar(self, thisIvar) == property)) { 
      key = [NSString stringWithUTF8String:ivar_getName(thisIvar)]; 
      break; 
     } 
    } 
    free(ivars); 
    return key; 
} 
+0

también debe 'libre (ivars)', de lo contrario, perderá la matriz. –

+0

buena captura, actualizada para reflejar eso. – hacksignal

+0

¿No devolverá esto el primer nombre de cualquier propiedad de la clase que coincida con el valor que transfiere? Ejemplo: https://gist.github.com/robskillington/684796bae2dd95592919 – rob

Respuesta

4

Puede obtener los nombres de las variables de instancia de una clase con la función Objective-C runtime APIclass_copyIvarList. Sin embargo, esto es bastante complicado, raramente realizado y casi nunca la mejor manera de lograr algo. Si tiene un objetivo más específico en mente que la mera curiosidad, podría ser una buena idea preguntar cómo lograrlo en Objective-C.

Además, por cierto, person.name no especifica una variable de instancia en Objective-C, es una llamada de propiedad. La variable de instancia sería person->name.

+0

No sabía que podía acceder a las variables de instancia de esa manera. Probablemente nunca lo use, pero es bueno saberlo. –

+0

@Brandon puedes hacer eso porque los objetos de Objective-C realmente son solo estructuras. :) –

+0

@Dave, Doh! –

0

Si la persona objeto está expuesta como una propiedad de la clase, puede usar objc_msgSend para obtener la valor.

Por lo tanto, si se pudiera acceder persona que utiliza

[object person] 

También puede hacer

objc_msgSend(object, "person") 

Para más detalles sobre el envío de mensajes, en particular cómo pasar argumentos a los métodos, consulte la Objective-C Runtime Programming Guide section on Messaging

2

Es posible utilizar stringification preprocesador y un trozo de cuerda haciendo girar:

NSUInteger lastIndexAfter(NSUInteger start, NSString *sub, NSString *str) { 
    NSRange found = [str rangeOfString:sub options:NSBackwardsSearch]; 
    if(found.location != NSNotFound) { 
     NSUInteger newStart = NSMaxRange(found); 
     if(newStart > start) 
      return newStart; 
    } 
    return start; 
} 

NSString *lastMember(NSString *fullName) { 
    if(!fullName) return nil; 

    NSUInteger start = 0; 
    start = lastIndexAfter(start, @".", fullName); 
    start = lastIndexAfter(start, @"->", fullName); 

    return [fullName substringFromIndex: start]; 
} 

#define NSStringify(v) (@#v) 
#define _NameofVariable_(v) lastMember(NSStringify(v)) 
33

Tan fácil como

#define VariableName(arg) (@""#arg)

Entonces haces:

NSObject *obj; 
NSString *str = VariableName(obj); 
NSLog(@"STR %@", str);//obj 
+0

¿Puedes explicar cómo funciona esto? :) –

+0

ahora que fue inesperado: D ¡Gracias de todos modos! –

+1

¿Alguien ha intentado esto?Pruebe VariableName (here_s_a_random_string_that_s_not_a_var) Esta no es una forma de obtener una propiedad o ivar para devolver su nombre. Esta es solo una forma de evitar que escriba @ "" alrededor de un texto, y en su lugar está usando VariableName(). ¿O me estoy perdiendo algo? – mahboudz

0

Los siguientes trabajos como una macro:

#define STRINGIZE(x) #x 
Cuestiones relacionadas