2012-04-14 1 views
4

Вот операции сравнения я хотел бы сделать: методКак динамически определять и сравнивать тип объектов ivars, используя ivar_getTypeEncoding & @encode?

// foobar is the name of an ivar on some class 
// i.e. NSDate *foobar; 
const char *ivarType = [self getTypeForInstanceVariableWithName:@"foobar"]; 
const char *objType = @encode(NSDate); 

if (strcmp(ivarType, objType) == 0) { 
    //set value 
} 

NSLog(@"comparing %s with %s", ivarType, objType); 

Helper:

- (const char*)getTypeForInstanceVariableWithName:(NSString *)name { 
    return ivar_getTypeEncoding(class_getInstanceVariable([self class], [name cStringUsingEncoding:NSUTF8StringEncoding])); 
} 

NSLog результат:

comparing @"NSDate" with {NSDate=#} 

Как со me @encode возвращает синтаксис другого типа, чем ivar_getTypeEncoding()? Есть ли лучший способ выполнить определение этого типа? Я должен упустить что-то здесь ... Спасибо!

ответ

5

При использовании ivar_getTypeEncoding() вы должны обратить внимание на первый символ. Давайте посмотрим пример:

Если у вас есть примитивный тип первый символ будет все, что вы получите, для Int это будет «я», для полукокса «C», для неподписанный долго долго " Q ', и т. Д.

Для объектов и классов вы можете получить больше, например, на вашем примере, но первый символ - это то, что вы хотите, например @ для объектов, # для классов:: для селекторов.

Вы можете прочитать об этих типах here. Вы также можете использовать константы при сравнении, например _C_ID, _C_CLASS и т. Д. У вас есть добыча на runtime.h.

C массивы, похоже, более сложны, но я уверен, что вы можете обойти это.

Одна из проблем вашего кода заключается в том, что вы получаете кодировку типа для класса NSDate, а не для объекта NSDate. Поэтому вместо сравнения с @encode (NSDate) сравнить с @encode (NSDate *).

Для просмотра этого кода, например, обратитесь к Adium's code.

+0

Отлично! спасибо за помощь, очень ценю это !!! – MTurner