2009-06-19 5 views
1

Ich habe questions/559482/why-doesnt-an-iphone-apps-main-function-ever-get-a-chance-to-finish gelesen, was erklärt, warum NSApplicationMain nie wirklich zurückkehrt. Das Gleiche passiert (aus dem gleichen Grund) in einer Desktop-Anwendung für Kakao, an der ich gerade arbeite.Wie kann ich NSLog in main(), aber außerhalb von NSApplicationMain verwenden?

Mit diesem Gedanken, Wie würde ich über die Verwendung von NSLog gehen, um einige abschließende Debugging-Nachrichten auszugeben, wenn meine Anwendung beendet?

genauer zu sein, würde Ich mag so etwas tun:

int myDebugVariable = 0; 

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    CMLog(@"application begin"); 

    int exitCode = NSApplicationMain(argc, (const char **) argv); 

    CMLog(@"application end. Debugging variable = %d", myDebugVariable); 

    [pool release]; 
    return exitCode; 
} 

In diesem Beispiel ist die „Anwendung beginnen“ Zeile auf die Konsole gedruckt wird, aber das „Anwendung Ende.“ Linie ist nicht.

Hinweis # 1: In meinem tatsächlichen Code verwende ich etwas komplizierter als myDebugVariable. Dies ist ein vereinfachtes Beispiel, das den Effekt veranschaulicht, den ich erreichen möchte.

Hinweis # 2: Ich bin vertraut mit der ApplicationWillTerminate Methode, die aufgerufen wird, wenn die Anwendung beendet wird, aber es ist nicht meine Bedürfnisse. Mein Debugging-Code basiert auf den dealloc Methoden für einige benutzerdefinierte Klassen, so dass es erst nach dem Aufruf von ApplicationWillTerminate ins Spiel kommt.


Update:

Adam Rosenfield's answer hat den Trick. Aus Gründen der Vollständigkeit ist hier eine Arbeitslösung:

int myDebugVariable = 0; 

void my_exit_handler(void) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    CMLog(@"application end: Debugging variable = %d", myDebugVariable); 

    [pool release]; 
} 

int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    CMLog(@"application begin"); 
    atexit(my_exit_handler); 

    int exitCode = NSApplicationMain(argc, (const char **) argv); 

    [pool release]; 
    return exitCode; 
} 
+0

Wenn Sie keine NSLog-Derivat-/Foundation-Klassen in Ihrem Exit-Handler verwenden, müssen Sie keinen Autorelease-Pool erstellen. Vergessen Sie auch nicht, dass einige Klassen niemals freigegeben werden, auch nicht bei Beendigung. –

+0

@Jason Coco: Guter Punkt. Ich hatte bereits entdeckt, dass einige Klassen nicht veröffentlicht wurden, aber es erwähnt hier. Wie für den Autorelease-Pool, würde printf funktionieren, aber ich habe mich an NSLog und NSString gewöhnt, also kann ich sie genauso gut benutzen :) –

+0

Große Frage und gute Antwort. Vielen Dank! –

Antwort

3

Verwenden atexit(3) einen Exit-Handler zu registrieren. Es wird automatisch aufgerufen, wenn Ihre App beendet wird, entweder indem Sie main beenden oder exit(3) aufrufen. Beispiel:

void my_exit_handler(void) 
{ 
    NSLog(@"about to exit, x = %d\n", x); 
} 

// at some point during app initialization... 
atexit(&my_exit_handler); 
+0

Ich musste ein anderes NSAutoreleasePool in my_exit_handler hinzufügen, damit dies funktioniert, aber es hat definitiv den Trick gemacht. Vielen Dank! –

Verwandte Themen