В любом случае, чтобы получить строку из имени переменной? - PullRequest
18 голосов
/ 21 марта 2010

Скажи, что у меня есть класс

@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;
}  

Ответы [ 5 ]

35 голосов
/ 26 февраля 2014

Так же просто, как

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

Тогда вы делаете:

NSObject *obj;
NSString *str = VariableName(obj);
NSLog(@"STR %@", str);//obj
4 голосов
/ 21 марта 2010

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

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

2 голосов
/ 21 марта 2010

Возможно, вы используете строковое преобразование препроцессора и немного перемешивания строк:

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))
0 голосов
/ 29 января 2017

Следующее работает как макрос:

#define STRINGIZE(x) #x
0 голосов
/ 21 марта 2010

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

Итак, если бы вы могли получить доступ к человеку, используя

[object person]

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

objc_msgSend(object, "person")

Подробнее об отправке сообщений, в том числе о том, как передавать аргументы в методы, см. В разделе Руководство по программированию среды выполнения Objective-C для обмена сообщениями

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...