Вывод iVars из метода описания? - PullRequest
1 голос
/ 17 сентября 2009

Я почти уверен, что просто упускаю суть и запутываюсь. Может кто-нибудь сказать мне, как я мог бы написать простое описание для объекта, который будет выводить значение переменных его экземпляра на консоль.

Кроме того: есть ли способ представить информацию в виде блока (т. Е. Если у вас было 10 iVars, это будет боль, заставляющая их всех возвращаться один за другим)

@interface CelestialBody : NSObject {
    NSString *bodyName;
    int bodyMass;
}

- (NSString *)description { 
    return (@"Name: %@ Mass: %d", bodyName, bodyMass);
}

ура -gary-

Ответы [ 4 ]

9 голосов
/ 17 сентября 2009
- (NSString*)description
{
  return [NSString stringWithFormat:@"Name: %@\nMass: %d\nFoo: %@",
     bodyName, bodyMass, foo];
}
5 голосов
/ 17 сентября 2009

Посмотрите на ответ на этот вопрос . Код воспроизводится ниже:

unsigned int varCount;

Ivar *vars = class_copyIvarList([MyClass class], &varCount);

for (int i = 0; i < varCount; i++) {
    Ivar var = vars[i];

    const char* name = ivar_getName(var);
    const char* typeEncoding = ivar_getTypeEncoding(var);

    // do what you wish with the name and type here
}

free(vars);
1 голос
/ 18 сентября 2009

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

// choose a short name for the macro
#define _f(x,...) [NSString stringWithFormat:x,__VA_ARGS__]

...

- (NSString *) description
{
    return _f(@"Name: %@ Mass: %d", bodyName, bodyMass);
}
1 голос
/ 18 сентября 2009

Как писал Джейсон, вы должны использовать stringWithFormat: для форматирования строк с использованием синтаксиса printf.

-(NSString*)description;
{
  return [NSString stringWithFormat:@"Name: %@ Mass: %d", bodyName, bodyMass];
}

Чтобы не писать это снова и снова для многих классов, вы можете добавить категорию в NSObject, которая позволит вам легко проверять переменные экземпляра. Это будет плохая производительность, но работает в целях отладки.

@implementation NSObject (IvarDictionary)

-(NSDictionary*)dictionaryWithIvars;
{
  NSMutableDictionary* dict = [NSMutableDictionary dictionary];
  unsigned int ivarCount;
  Ivar* ivars = class_copyIvarList([self class], &ivarCount);
  for (int i = 0; i < ivarCount; i++) {
    NSString* name = [NSString stringWithCString:ivar_getName(ivars[i])
                                        encoding:NSASCIIStringEncoding];
    id value = [self valueForKey:name];
    if (value == nil) {
      value = [NSNull null];
    }
    [dict setObject:value forKey:name];
  }
  free(vars);
  return [[dict copy] autorelease]; 
}
@end

С этим описанием реализации также можно легко разобраться:

-(NSString*)description;
{
  return [[self dictionaryWithIvars] description];
}

Не добавляйте description как категорию в NSObject, иначе вы можете получить бесконечные рекурсии.

...