-(void) dispose

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • -(void) dispose

    Hi Leute,

    ich habe ein kleines "Problemchen", ich versuche rauszufinden wie "wir" das Problem mit Objekten lösen die externe Ressourcen verwenden.
    Ein einfaches Beispiel wöre eine Logger-Klasse die in verschiedenen Dateien Ausgaben protokoliert. Dazu gibts dann eine
    -(id) initWithFileName:(NSString *)aFilename
    Methode die bei Aufruf eine Datei-Objekt erzeugt.
    Sobald das Logging in die eine spezielle Datei nicht mehr benötigt wird, möchte ich die Datei schließen und das Objekt loswerden. Und hier liegt der Hund begraben, haben "wir" für diese Aufräumarbeiten eine Standard-Methode? Ich denke da an sowas wie die Dispose() Methode in C#.

    Mein Code zum "Schließen" des Loggers würde dann so aussehen:
    [logger dispose];
    [logger release];
    logger = nil;

    Damit stelle ich sicher, dass die Log-Datei immer geschlossen wird und es ist egal ob mit oder ohne GC gearbeitet wird.
    Die spannende Frage ist jetzt, nennen "wir" so ne Aufräummethode dispose oder hat Apple da was eigenes und ich habs nur nicht gefunden.

    Man liest sich
    PEter
    http://pdps.mybrute.com/
  • Hi,

    weder dealloc noch finalize sind die Lösung.
    1) Apple sagt selber, man soll dealloc nicht dafür nehmen. Man weiß zum Beispiel nicht, ob dealloc überhaupt aufgerufen wird.
    2) Bei finalize gibts die gleichen Problemchen!

    Weil das eben nicht funktioniert (dealloc und finalize sind nur für die Rückgabe des Speichers verantwortlich) suche ich nach einer "offiziellen Bezeichnung" für eine Routine in der ich Ressourcen freigeben will.
    Anders ausgedrückt, das Problem ist gelöst ich brauche nur noch nen Namen für das Kind!

    Man liest sich
    Peter
    http://pdps.mybrute.com/


  • Davon rät Apple selber ab, sowas zu machen (u.a. die Tatsache, dass die Aufrufreihenfolge von finalize nicht definiert ist, kann grosse Probleme bereiten).

    Für nen Application-globalen Logger wäre es m.M.n. am sichersten, sich als Oberserver für NSApplicationWillTerminateNotification einzuhängen und da dann den Logger zu schließen.
    Auch eine Singleton-Implementation (siehe Cocoa-Fundamentals-Guide, Object creation) über ne Klassenfaktory ( logger = [ Logger sharedInstance ]; ) wäre denkbar. Da könntest Du das Filehandling dann verbergen (direkt in der Logging-funktion?).

    Gruß, SMJ
  • Hi SMJ,

    die Idee mit dem Singelton ist ganz nett, aber hier im Beispiel will ich mehrere Instanzen haben.

    Die dispose-Methode habe ich mir übrigens aus C# geliehen, aber wie schon geschrieben ich wollte eigentlich nur wissen ob das Kind den richtigen Namen hat. Ich hätte auch Hugo (oder Steve) verwenden können, dann haben die anderen vielleicht nicht so viel Angst vor der Mehtode ;)


    Man liest sich
    Peter
    http://pdps.mybrute.com/
  • Original von pstoehr
    Hi,

    weder dealloc noch finalize sind die Lösung.
    1) Apple sagt selber, man soll dealloc nicht dafür nehmen. Man weiß zum Beispiel nicht, ob dealloc überhaupt aufgerufen wird.
    2) Bei finalize gibts die gleichen Problemchen!

    Weil das eben nicht funktioniert (dealloc und finalize sind nur für die Rückgabe des Speichers verantwortlich) suche ich nach einer "offiziellen Bezeichnung" für eine Routine in der ich Ressourcen freigeben will.
    Anders ausgedrückt, das Problem ist gelöst ich brauche nur noch nen Namen für das Kind!

    Man liest sich
    Peter


    ist denn das so tragisch wie du das nennst?
    flsuhAndClose, close, cleanUp, invalidate ...
  • Original von pstoehr
    Hi,

    weder dealloc noch finalize sind die Lösung.
    1) Apple sagt selber, man soll dealloc nicht dafür nehmen. Man weiß zum Beispiel nicht, ob dealloc überhaupt aufgerufen wird.
    2) Bei finalize gibts die gleichen Problemchen!

    Weil das eben nicht funktioniert (dealloc und finalize sind nur für die Rückgabe des Speichers verantwortlich) suche ich nach einer "offiziellen Bezeichnung" für eine Routine in der ich Ressourcen freigeben will.
    Anders ausgedrückt, das Problem ist gelöst ich brauche nur noch nen Namen für das Kind!

    Man liest sich
    Peter

    Habt ihr das als Quote (damit ich da nicht selber mal drauf reinfalle…)? Weil in der NSObject Documentation steht es ja sogar als Beispiel:

    Quellcode

    1. - (void)finalize {
    2. if (log_file != NULL) {
    3. fclose(log_file);
    4. log_file = NULL;
    5. }
    6. [super finalize];
    7. }
  • Aber wenn man nix großartiges machen will, also keine neuen Objekte erstellen, oder sich nicht mit anderen Objecten unterhalten will sagen sie doch auch selber das es kein Problem ist, und wenn er nur die Logdatei schließen will in die er geschrieben hat dann sollte das doch kein Problem sein oder was hab ich übersehen?
  • Hi,
    Original von gritsch
    ist denn das so tragisch wie du das nennst?
    flsuhAndClose, close, cleanUp, invalidate ...

    im Prinzip nicht, wie gesagt ich könnte die Methode auch Hugo oder Steve nennen, aber da ich nicht der erste bin der sowas macht, würde ich mich halt gerne den Gepflogenheiten anpassen. Vielleicht ist dieses "Make things right" auch nur ein Tick von mir.

    Man liest sich
    Peter
    http://pdps.mybrute.com/
  • Original von karrade
    Aber wenn man nix großartiges machen will, also keine neuen Objekte erstellen, oder sich nicht mit anderen Objecten unterhalten will sagen sie doch auch selber das es kein Problem ist, und wenn er nur die Logdatei schließen will in die er geschrieben hat dann sollte das doch kein Problem sein oder was hab ich übersehen?


    Es darf dann kein anderes Objekt mehr den Logger benutzen (in dessen finalize-Methode), denn deren Aufrufreihenfolge ist nicht festgelegt.
    Grundsätzlich sollte man wann immer möglich versuchen, aus den Speicherveraltungsmethoden (dealloc, finalize), alles herauszuhalten, was nicht mit Speicherverw. zu tun hat.

    Zitat Apple-Doku zu diesem Thema:
    In an ideal scenario, you should have closed the file descriptor before the finalize method is called
  • Hi,
    Original von karrade
    Aber wenn man nix großartiges machen will, also keine neuen Objekte erstellen, oder sich nicht mit anderen Objecten unterhalten will sagen sie doch auch selber das es kein Problem ist, und wenn er nur die Logdatei schließen will in die er geschrieben hat dann sollte das doch kein Problem sein oder was hab ich übersehen?

    in dem Artikel von Apple wird ja gesagt, dass es nicht "Das Gelbe vom Ei" ist. Ausserdem habe ich nirgends gelesen dass der Aufruf von finalize garantiert wird.
    Wenn man diese beiden Dinge zusammennimmt heißt es (zumindest für mich), man muss selber dafür sorgen wenn die externen Ressourcen sicher freigegeben werden. Und spätesten wenn man ohne GC arbeitet (warum auch immer) muss man so ein dispose haben. Bei release wird nämlich explizit geschrieben, dass es keine Garantie gibt dass es immer aufgerufen wird.

    Man liest sich
    Peter
    http://pdps.mybrute.com/
  • Ja das mit der Aufrufreihenfolge hab ich schon verstanden kommt halt drauf an wie der GC grade drauf ist…
    Aber grade das mit der Logger Klasse wird doch von Apple als Beispiel genommen, File schließen ok, tschüss sagen nicht. Aber war das nicht grade das Thema des eingangs Posts? Das er das File noch schließen will?
  • Vielleicht (sogar mutmaßlich) habe ich hier etwas verpasst. >Falls nicht, verstehe ich die gesamte Diskussion nicht:

    a) Inhalt kann doch wohl nicht der Name der Methode sein!? Nenne sie -hannoSeppCornflakes.

    b) Es handelt sich offenkundig um keinen Singleton (warum auch immer). Wenn es kein Singleton ist, dann muss es einen Eigentümer geben. Wenn es einen Eigentümer gibt, ist der für das Aufräumen zuständig.

    c) Programmbeendigung und damit aufräumen ist eine Sache von applicationWillTerminte:. Wurde schon erwähnt.

    d) Warum erhält ein Objekt manchmal kein -release? Richtig, weil Cocoa weiß, dass bei Prozessende ohnehin alle Ressourcen freigegeben werden. Dazu gehört auch der Speicher. Und wer noch?

    e) Mir fällt gerade ein Problem bei meiner AOP-Lösung auf. Danke!
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von SumpfMonster
    Ja, gut auf den Punkt gebracht.
    Logging wäre ja mit AOP-Support ganz easy, ist da von seiten Apple eigentlich irgendwas geplant?

    Das weiß ich nicht. Aber bei mir ist etwas geplant.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von Amin Negm-Awad
    d) Warum erhält ein Objekt manchmal kein -release? Richtig, weil Cocoa weiß, dass bei Prozessende ohnehin alle Ressourcen freigegeben werden. Dazu gehört auch der Speicher. Und wer noch?


    Das ist jetzt interessant für mich. Was steckt hinter dem noch?
    Es gibt genau 10 Sorten von Menschen.
    Die eine kennt das binaere Zahlensystem, die andere nicht.
  • Original von mac_held
    Original von Amin Negm-Awad
    d) Warum erhält ein Objekt manchmal kein -release? Richtig, weil Cocoa weiß, dass bei Prozessende ohnehin alle Ressourcen freigegeben werden. Dazu gehört auch der Speicher. Und wer noch?


    Das ist jetzt interessant für mich. Was steckt hinter dem noch?

    Dateien werden geschlossen.

    Aber nein,ich will das nicht als die Lösung propagieren. Eine Lösung scheint mir ineinem Designzu liegen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Nicht ganz ohne Risiko - das funktioniert sehr lange, aber leider nicht immer.


    C-Quellcode

    1. #include <stdlib.h>
    2. #include <stdio.h>
    3. #include <signal.h>
    4. int main(int argc, char **argString)
    5. { char tempBuffer[10240];
    6. FILE *lehmi=fopen( "/tmp/dummyfile", "w+" );
    7. if ( lehmi != NULL )
    8. { int ugh=0;
    9. setvbuf( lehmi, tempBuffer, _IOFBF,sizeof(tempBuffer) );
    10. for ( ugh=0;ugh<1024;ugh++ )
    11. fprintf( lehmi, "%d\n", ugh );
    12. }
    13. if ( argc > 1 )
    14. kill( getpid(), 9 );
    15. return 0;
    16. }
    Alles anzeigen


    Wenn man das Programm normal startet ist alles so wie man will, gibt man ein Parameter mit, dann ist alles so, wie man es nicht will.

    Das gilt für alle Signale, die ein Programmende herbeiführen (für die kein Trap existiert) - AUCH SIGSEGV, SIGBUS ...

    Edith meint: das soll jetzt nicht besserwisserisch rüber kommen, sondern eher Leute davon abzuhalten, sich auf das OS zu verlassen. Wenn das Programm nämlich mit SIGBUS abkachelt, dann ist das offene File auch im Lokus, wenn vorher nicht sauber geflusht wurde.
    Es gibt genau 10 Sorten von Menschen.
    Die eine kennt das binaere Zahlensystem, die andere nicht.