2009-11-25 6 views
3

J'imprime quelque chose à la console en utilisant NSLog(). Y at-il un moyen de passer tous les arguments de la méthode actuelle à NSLog(), ou à toute autre fonction ou méthode, sans les regarder explicitement?Passer tous les arguments d'une méthode dans NSLog

Par exemple, j'ai déjà une macro qui imprime des informations utiles à la console quand je viens de mettre LOGME dans mon code. La macro va créer un appel à la méthode de journalisation d'une classe singleton et passer plusieurs choses utiles comme _cmd et d'autres choses.

Je voudrais aussi attraper tous les arguments de cette méthode et les transmettre pour les imprimer automatiquement. Est-ce possible?

Répondre

3

Utiliser gdb. Vous pouvez définir un point d'arrêt qui consigne les arguments dans la méthode et continue. Si vous insistez pour le faire à la dure ... Ce n'est certainement pas simple, mais vous pouvez utiliser la structure de pile sur une architecture/ABI donnée et utiliser l'environnement d'exécution Objective-C pour déterminer le nombre d'arguments et de quelle taille chercher. À partir de maintenant, je suis en territoire inconnu; Je n'ai jamais fait ça et je ne m'en soucierais jamais. Donc YMMV ...

Dans votre méthode, vous pouvez obtenir la structure Method, puis le nombre d'arguments, puis chaque type d'argument et sa taille. Vous pouvez ensuite marcher la pile de l'adresse du paramètre self (c.-à-&self), en supposant saviez ce que vous faisiez ...

Method method = class_getInstanceMethod([self class], _cmd); 
unsigned nargs = method_getNumberOfArguments(method); 
void *start = &self; 
for(unsigned i = 0; i<nargs; i++) { 
    char *argtype = method_copyArgumentType(method, i); 
    //find arg size from argtype 
    // walk stack given arg zie 
    free(argtype); 
} 

En chemin, vous auriez à convertir la chaîne de argtype (en utilisant Objective-C type encodings) à la taille de chaque argument de la pile.

Bien sûr, vous devez dériver la chaîne de format pour chaque type et appeler NSLogv avec un tableau d'arguments variable approprié contenant les arguments copiés à partir de leur emplacement sur la pile. Probablement beaucoup plus de travail que sa valeur. Utilisez le débogueur.

+0

Vous ne voulez pas l'adresse de la variable 'self'? À partir du pointeur d'objet * dans * la variable 'self' n'imprime pas les arguments de la méthode; c'est l'impression des variables d'instance de l'objet (probablement comme garbage, puisque vous utiliseriez les types d'arguments method pour le guidage [mis]). –

+0

Oui, absolument, à partir de & self. –

+0

Voilà ce que je veux dire: "start" ne devrait-il pas être initialisé à "& self", pas "self"? –

3

Il est impossible d'adresser tous les arguments du préprocesseur ou d'Objective-C.

La seule façon dont je suis conscient est en utilisant le débogueur. Vous pouvez ajouter une action de point d'arrêt dans Xcode pour le faire facilement. Faites un clic droit dans la colonne la plus à gauche d'une fenêtre de code, sélectionnez "Points d'arrêt intégrés" -> "Point d'arrêt et arguments du journal et auto-continue".

+0

Comment le débogueur le fait-il alors? –

+3

Le débogueur a des connaissances sur l'ABI (conventions d'appel) et utilise des symboles de débogage (créés par le compilateur) pour mapper les adresses dans le code et s'enregistre dans les emplacements et les variables des fichiers source. En bref: Il utilise tout un tas de trucs qui ne font pas partie du langage. –

Questions connexes