NSLog den Methodennamen mit Objective-C im iPhone

Lesezeit: 4 Minuten

Benutzeravatar von vodkhang
Wodkhang

Derzeit definieren wir uns selbst einen erweiterten Protokollmechanismus, um den Klassennamen und die Quellzeilennummer des Protokolls auszugeben.

#define NCLog(s, ...) NSLog(@"<%@:%d> %@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], \
    __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__])

Wenn ich zum Beispiel NCLog(@”Hallo Welt”); Die Ausgabe wird sein:

<ApplicationDelegate:10>Hello world

Jetzt möchte ich auch den Methodennamen wie folgt abmelden:

<ApplicationDelegate:applicationDidFinishLaunching:10>Hello world

Das würde unser Debugging also einfacher machen, wenn wir wissen, welche Methode aufgerufen wird. Ich weiß, dass wir auch den Xcode-Debugger haben, aber manchmal möchte ich auch debuggen, indem ich mich abmelde.

  • In meinem letzten iPhone Projekt, habe ich das tatsächlich manuell gemacht. Würde gerne die Antwort darauf sehen.

    – Jakob Relkin

    5. Mai 2010 um 2:46 Uhr


  • Mögliches Duplikat: stackoverflow.com/questions/969130/…

    – erkanyildiz

    7. Mai 2014 um 14:03 Uhr

Der Benutzeravatar von drawonward
nach vorne gezogen

print(__FUNCTION__) // Swift
NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C

Swift 3 und höher

print(#function)

  • Solltest du wirklich nutzen NSLog(@"%@", NSStringFromSelector(_cmd))wenn Sie verwenden werden _cmdda AFAIK Apple erklärt _cmd als Typ SEL, keine C-Saite. Nur weil es zufällig als C-String implementiert ist (ab den aktuellen Versionen von Mac OS X und iPhone OS), heißt das nicht, dass Sie es so verwenden sollten, da Apple es in einem Betriebssystem-Update ändern könnte.

    – Nick Forge

    5. Mai 2010 um 8:06 Uhr

  • Ja, NSStringFromSelector ist die richtigere Antwort. Ich verwende _cmd nie als C-String für etwas anderes als Debug-Code.

    – nach vorne gezogen

    6. Mai 2010 um 0:17 Uhr

  • Wow, der Compiler beschwert sich über Zeigerinkompatibilität, aber es funktioniert … Also _cmd (Typ: SEL) wirklich ist ein Char* !?

    – Nikolaus Miari

    19. Juni 2012 um 9:46 Uhr


  • Methodenaufrufe wie [self doSomething:arg1 somethingElse:arg2] in den C-Funktionsaufruf umgewandelt werden objc_msgSend(self, "doSomething:somethingElse:, arg1, arg2);. Der zweite Parameter von objc_msgSend() nimmt ein char*. Denken Sie daran, dass die Objective-C-Laufzeit, da sie dynamisch ist, tatsächlich eine Nachschlagetabelle verwendet, um herauszufinden, welche Methode für welche Klasse aufgerufen werden soll, sodass ein char* bequem ist, da Methoden als Zeichenfolgen in der Nachschlagetabelle dargestellt werden.

    – Jack Lawrence

    7. November 2012 um 16:42 Uhr

  • Für Swift 2.2 verwenden sollte print("\(#function)")

    – Jake Lin

    29. März 2016 um 5:43 Uhr


Um Ihre Frage technisch zu beantworten, möchten Sie:

NSLog(@"<%@:%@:%d>", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);

Oder Sie könnten auch Folgendes tun:

NSLog(@"%s", __PRETTY_FUNCTION__);

  • Mit __FUNCTION__ und sein hübsches Äquivalent ist auch in C-Funktionen verfügbar.

    – Georg Fritzsche

    5. Mai 2010 um 3:21 Uhr


  • NB __FUNCTION__ enthält auch den Klassennamen

    – Orangenhund

    7. März 2014 um 10:26 Uhr

  • gibt es einen Unterschied bei der Verwendung von NSLog(@”%s”,_func_); ODER NSLog(@”%s”, _PRETTY_FUNCTION_) ???

    – Ravi

    10. April 2018 um 10:35 Uhr


Benutzeravatar von Basil Bourque
Basil Bourque

tl;dr

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

Einzelheiten

Apple hat eine Seite mit technischen Fragen und Antworten: QA1669 – Wie kann ich meinen Protokollierungsanweisungen Kontextinformationen hinzufügen, z. B. die aktuelle Methode oder Zeilennummer?

Zur Unterstützung bei der Protokollierung:

  • Der C-Präprozessor stellt einige bereit Makros.
  • Objective-C bietet Ausdrücke (Methoden).
    • Übergeben Sie die implizites Argument für den Selektor der aktuellen Methode: _cmd

Wie andere Antworten angegeben haben, rufen Sie Folgendes auf, um lediglich den Namen der aktuellen Methode zu erhalten:

NSStringFromSelector(_cmd)

Um den aktuellen Methodennamen zu erhalten und aktuelle Zeilennummer, verwenden Sie diese beiden Makros __func__ und __LINE__ wie hier zu sehen:

NSLog(@"%s:%d someObject=%@", __func__, __LINE__, someObject);

Ein weiteres Beispiel… Codeschnipsel, die ich in der Code-Snippet-Bibliothek von Xcode aufbewahre:

NSLog( @"ERROR %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

…und TRACE statt ERROR…

NSLog( @"TRACE %@ METHOD %s:%d ", @"DescriptionGoesHere", __func__, __LINE__ );

…und eine längere mit einer weichcodierten Beschreibung, die einen Wert übergibt ([rows count])…

NSLog( @"TRACE %@ METHOD %s:%d.", [NSString stringWithFormat:@"'Table of Contents.txt' file's count of Linefeed-delimited rows: %u.", [rows count]] , __func__, __LINE__ );

Präprozessor-Makros für die Protokollierung

Beachten Sie die Verwendung von a Paar Unterstrich Zeichen auf beiden Seiten des Makros.

| Macro                | Format   | Description
  __func__               %s         Current function signature
  __LINE__               %d         Current line number
  __FILE__               %s         Full path to source file
  __PRETTY_FUNCTION__    %s         Like __func__, but includes verbose
                                    type information in C++ code. 

Ausdrücke für die Protokollierung

| Expression                       | Format   | Description
  NSStringFromSelector(_cmd)         %@         Name of the current selector
  NSStringFromClass([self class])    %@         Current object's class name
  [[NSString                         %@         Source code file name
    stringWithUTF8String:__FILE__]   
    lastPathComponent] 
  [NSThread callStackSymbols]        %@         NSArray of stack trace

Protokollierungs-Frameworks

Einige Protokollierungs-Frameworks können auch beim Abrufen der aktuellen Methode oder Zeilennummer hilfreich sein. Ich bin mir nicht sicher, da ich ein großartiges Protokollierungsframework in Java verwendet habe (SLF4J + Wieder anmelden) aber nicht Kakao.

In dieser Frage finden Sie Links zu verschiedenen Cocoa-Protokollierungsframeworks.

Name des Selektors

Wenn Sie eine Selektor-Variable (a AUSW), können Sie den Namen der Methode (“Nachricht”) auf zwei Arten drucken, wie hier beschrieben Codec Blogeintrag:

  • Verwenden von Objective-C-Aufruf zu NSStringFromSelector:
    NSLog(@"%@", NSStringFromSelector(selector) );
  • Mit geradem C:
    NSLog(@"%s", selector );

Diese Informationen stammen aus der verlinkten Apple-Dokumentationsseite mit Stand vom 19.07.2013. Diese Seite wurde zuletzt am 04.10.2011 aktualisiert.

  • Verwenden Sie für C sel_getName(SEL) da SEL ein undurchsichtiger Typ ist und nicht immer a sein muss char *

    – Ethan Reesor

    3. Dezember 2013 um 0:31 Uhr

Benutzeravatar von Huynh Inc
Huynh Inc

NSLog(@"%@", NSStringFromSelector(_cmd)); // Objective-C
print(__FUNCTION__) // Swift

Es ist eigentlich genauso einfach wie:

printf(_cmd);

Aus irgendeinem Grund lässt iOS zu, dass _cmd als wörtliches Zeichen ohne eine Kompilierungswarnung übergeben wird. Wer weiß

Benutzeravatar von garg
garg

Bei Swift 4:

Funktionstest () {

print(#function)

}

test() //drucke den Wert “test()”

1424580cookie-checkNSLog den Methodennamen mit Objective-C im iPhone

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy