2009-09-17 7 views
1

Je suis assez sûr que je manque juste le point ici et devenir confus. Quelqu'un peut-il me dire comment je pourrais écrire une description simple pour un objet qui imprimera la valeur de ses variables d'instance à la console.Sortir iVars de la méthode de description?

aussi: est-il de toute façon de présenter l'information comme un bloc (si vous aviez 10 Ivars ça va être une douleur les amener tous à retourner un par un)

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

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

acclamations -Gary-

Répondre

9
- (NSString*)description 
{ 
    return [NSString stringWithFormat:@"Name: %@\nMass: %d\nFoo: %@", 
    bodyName, bodyMass, foo]; 
} 
+0

Merci les gars, j'oubliais que j'avais besoin de formater la chaîne en utilisant NSString. Très apprécié ... – fuzzygoat

+1

@quinn: merci de ne pas modifier mes messages de manière arbitraire. Si j'ai une faute d'orthographe ou quelque chose et que vous cherchez désespérément à le réparer, n'hésitez pas, mais ne reformatez pas arbitrairement mes extraits de code dans votre style préféré. Cela n'ajoute aucune valeur. –

5

Regardez la réponse à this question. Le code est reproduit ci-dessous:

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); 
+0

Ceci est utile dans un sens générique, mais la réponse de Jason résout le problème que le demandeur avait avec l'utilisation correcte d'une chaîne de format. –

+0

Si vous avez le nom de l'ivar alors utiliser 'valueForKey:' pour obtenir la valeur de l'ivar via KVC supprime le fardeau de vérifier le type pour vous, tout est alors un objet. – PeyloW

1

Comme Jason écrit, vous devez utiliser stringWithFormat: pour les chaînes de format avec printf comme la syntaxe.

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

Pour éviter d'écrire encore et encore pour de nombreuses classes, vous pouvez ajouter une catégorie sur NSObject qui vous permet de facilement contrôler les variables d'instance. Ce sera une mauvaise performance, mais fonctionne à des fins de débogage.

@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 

Avec cela en place est également mise en œuvre de description d'un morceau de gâteau:

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

Ne pas ajouter ce description comme une catégorie sur NSObject, ou vous pourriez vous retrouver avec des récurrences infinies.

1

Ce n'est pas une mauvaise idée de ce que vous avez là, c'est presque réalisable aussi.

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

... 

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

Merci, je me suis toujours demandé comment je pourrais raccourcir cet idiome stringWithFormat trop verbeux, mais je ne savais pas comment faire var args dans les macros. Maintenant, je le fais :) –

+0

En guise de remarque, vous pouvez envisager d'utiliser '## __ VA_ARGS__' pour un traitement d'argument variadique plus générique dans les macros; sinon vous obtiendrez probablement une erreur de compilation pour quelque chose comme 'return _f (@" Name is foo ");', où vous ne fournissez pas de liste d'arguments variadiques dans l'invocation. – fullofsquirrels

+0

@fullofsquirrels: mais pourquoi utiliser '_f (@" str ")' quand vous devriez juste utiliser '@" str "'? – dreamlax

Questions connexes