2010-10-28 3 views
30

Die Laufzeit von Objective-C scheint ziemlich robust zu sein, also habe ich mich gefragt, ob es eine Möglichkeit gibt, den Namen der Funktion zu protokollieren, die die aktuelle Funktion genannt hat.Drucken Sie den Namen der aufrufenden Funktion in das Debug-Protokoll

Meine Situation ist, dass eine Reihe von Dingen zu einer Eigenschaft zuweisen, und anstatt einen Haltepunkt zu setzen und den Aufruf Stapel jedes Mal zu untersuchen, möchte ich nur NSLog den Namen der Funktion, die die Eigenschaft setzt, entlang mit dem neuen Wert.

So ist es möglich, zur Laufzeit Zugriff auf den Call-Stack zu bekommen?

Antwort

42

Versuchen Sie folgendes:

#include <execinfo.h> 

void *addr[2]; 
int nframes = backtrace(addr, sizeof(addr)/sizeof(*addr)); 
if (nframes > 1) { 
    char **syms = backtrace_symbols(addr, nframes); 
    NSLog(@"%s: caller: %s", __func__, syms[1]); 
    free(syms); 
} else { 
    NSLog(@"%s: *** Failed to generate backtrace.", __func__); 
} 
+0

Das funktioniert gut, wenn Sie 'sizeof (addr)' durch 'sizeof (addr)/sizeof (void *)' (oder nur 2) ersetzen. Vielen Dank! – Brian

+14

Behoben. Oh, und Foundation stellt dies wirklich wirklich einfach über '- [NSThread callStackSymbols]', die ein Array zurückgibt. Sie könnten es als 'NSArray * syms = [[NSThread currentThread] callStackSymbols]; if ([symms count]> 1) NSLog (@ "caller:% @", [symys objectAtIndex: 1U]; ' –

+5

letzter Kommentar:' callStackSymbols' ist eine Klassenmethode. Sie müssen sie als '[NSThread callStackSymbols]' verwenden – user102008

2

Es gibt keine Möglichkeit, den Absender zu erhalten. Oder zumindest nichts, das auf Objective-C abzielt.

Es gibt jedoch ein paar Alternativen.

Zuerst könnten Sie GDB-Befehle verwenden. Gehen Sie auf die GDB-Konsole und so etwas wie:

comm 1 
bt 
po argName 
cont 

Alternativ können Sie DTrace verwenden. Das ist schwer. Oder Sie könnten Instrumente verwenden, was dtrace etwas einfacher macht.

Oder Sie könnten die Funktion backtrace() verwenden. Siehe die Backtrace-Manpage (x-man-page: // backtrace).

0

Es gibt ein C-Makro namens __PRETTY_FUNCTION__, das eine C-Zeichenfolge mit dem Namen der aktuellen Funktion zurückgibt. Falls Sie Fragen zu einem NSString konvertieren möchten für leicht Druck auf NSLog, können Sie ein Makro mit

#define NSSTRING_PRETTY_FUNCTION [NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSASCIIStringEncoding] 

schaffe ich es die ganze Zeit in meinen Projekten verwenden.

+4

Sie haben die Frage nicht richtig gelesen. Es ist nicht der Name der aktuellen Funktion, sondern der Aufrufer. – JeremyP

30

große Frage. Wenn Sie die obige Antwort von Jeremy kombinieren und was wir immer für unser Debugging verwenden, erhalten Sie eine nette Zeichenfolge wie diese:

+0

Müssen Sie dieses Stück Code irgendwo anrufen? – Shamsiddin

+0

Ja, Sie müssen dies in der jeweiligen Funktion aufrufen, wo Sie das Protokollieren möchten call. – LordT

+0

Ich tat, wie Sie sagten, aber er druckte nicht alle Hist ory der bearbeiteten Methoden beginnen vom Projektlauf. – Shamsiddin

Verwandte Themen