2010-03-20 2 views
18

Скажем, у меня есть свой классВ любом случае, чтобы получить строку из имени переменной?

@interface Person : NSObject { NSString *name; } 

мне нужно получить имя NSString в пределах моего класса

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

Спасибо за ответы, вот решение, которое я придумал из ответов

//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

вы также должны 'free (ivars)', иначе вы пропустите массив. –

+0

хороший улов, обновленный, чтобы отразить это. – hacksignal

+0

Не будет ли это просто вернуть первое имя какого-либо свойства класса, которое соответствует значению, которое вы передаете? Пример: https://gist.github.com/robskillington/684796bae2dd95592919 – rob

ответ

4

Вы можете получить имена переменных экземпляра класса с помощью функции Objective-C runtime APIclass_copyIvarList. Однако это скорее связано, редко делается и почти никогда не является лучшим способом добиться чего-то. Если у вас есть более конкретная цель, чем просто любопытство, может быть неплохо спросить о том, как выполнить ее в Objective-C.

Кроме того, кстати, person.name не указывает переменную экземпляра в Objective-C - это вызов свойства. Переменная экземпляра будет person->name.

+0

Я не знал, что вы можете обращаться к переменным экземпляра таким образом. Вероятно, он никогда не будет использовать его, но хорошо знать. –

+0

@Brandon вы можете это сделать, потому что объекты Objective-C на самом деле просто структурированы. :) –

+0

@Dave, Doh! –

0

Если объект человека выставлен как свойство класса, вы можете использовать objc_msgSend для получения стоимость.

Так что, если вы могли бы получить доступ к человеку с помощью

[object person] 

Вы также можете сделать

objc_msgSend(object, "person") 

Для получения более подробной информации о отправки сообщения, в том числе, как передать аргументы методов, см Objective-C Runtime Programming Guide section on Messaging

2

Вы можете использовать препроцессор stringification и немного струнные кручений-верчений:

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

Как легко, как

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

Тогда вы:

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

Можете ли вы объяснить, как это работает? :) –

+0

теперь это было неожиданно: D Спасибо в любом случае! –

+1

Кто-нибудь пробовал это?Попробуйте VariableName (here_s_a_random_string_that_s_not_a_var) Это не способ получить свойство или ivar, чтобы вернуть его имя. Это всего лишь способ избавить вас от ввода @ "вокруг некоторого текста - и вместо этого вы используете VariableName(). Или я чего-то не хватает? – mahboudz

0

следующих работы как макрос:

#define STRINGIZE(x) #x 
Смежные вопросы