Frage

Beachten Sie die folgenden Cocoa / Obj-C-Code-Schnipsel:

MyClass *obj;
@try {
    [obj doSomething];
}
@catch (NSException * e) {
    NSLog(@"Exception occurred: %@", [e description]);
}
@finally {
    [obj cleanUp];
}

und

MyClass *obj;
@try {
    [obj doSomething];
}
@catch (NSException * e) {
    NSLog(@"Exception occurred: %@", [e description]);
}
[obj cleanUp];

Unter welchen Umständen wird das erste Schnipsel Ergebnis in [obj cleanUp] aufgerufen wird, während die zweite nicht führen in [obj cleanUp] aufgerufen wird? Mit anderen Worten, unter welchen Umständen ist @finally nicht-redundante wenn Cocoa Ausnahmebehandlung mit?

War es hilfreich?

Lösung

In diesem Fall, in dem Sie die Ausnahme sind Quetschen, keine. @finally wird verwendet, bis zu reinigen, wenn Sie entweder nicht die Ausnahme abfangen, oder rethrow es, in jedem Fall verläßt endgültigen Ausnahme-Antwortcode zu rufen. Da Ausnahmen in Cocoa nur für Programmierfehler werden sollen verwendet und somit tritt selten auf, ist dies ein ganz vernünftig, was zu tun ist.

Es ist auch erwähnenswert, einen Fall, in dem Sie nicht müssen @finally verwenden, das ist, wenn Sie Ihren eigenen Autofreigabepool einrichten. Wenn die „Eltern“ Autofreigabepool zerstört wird, werden alle inneren diejenigen, die sein noch haben aufgeräumt werden auch nicht. Wenn Sie es versuchen, sich zu reinigen, müssen Sie die Ausnahme selbst aus Ihrem Autofreigabepool fördern.

Andere Tipps

In diesen Szenarien gibt es keinen Unterschied, weil die Ausnahme geschluckt wird. Hier sind zwei Szenarien, in denen es ist ein Unterschied:

[obj Cleanup] heißt:

MyClass *obj;
@try {
    [obj doSomething];
}
@catch (NSException * e) {
    @throw;      
}
@finally {
    [obj cleanUp]; // called when exception is caught
}

[obj Cleanup] nicht genannt:

MyClass *obj;
@try {
    [obj doSomething];
}
@catch (NSException * e) {
    @throw;
}
[obj cleanUp]; // not called when exception is caught

Es ist auch erwähnenswert, dass Code in @finally Blöcken der Feststellung wird ausgeführt, wenn die Steuerung des @try Block aus irgendeinem Grunde beendet , auch über return oder goto. Zum Beispiel:

@try {
    doStuff();
    if(bail){
        return;
    }
    doMoreStuff();
}
@finally {
    [obj cleanUp];
}
[obj announceSuccess];

[obj cleanUp] wird ausgeführt, selbst wenn bail wahr ist, aber [obj announceSuccess] nicht.

Wann:

  • Sie fangen nicht die Art der Ausnahme, die aufgetreten
  • Sie fing die Ausnahme, aber der Code im catch-Block wirft auch eine Ausnahme.

Eine untere Ebene Frage, warum machst du das?

Die try / catch / finally Ansatz weit in Java verwendet wird, aber so gut wie nie in Objective-C verwendet, und ist kein bevorzugter Ansatz - Sie einfach brauchen es nicht als Bibliotheken werden keine Ausnahmen, wie Java-Bibliothek Anrufe würden werfen, und wenn Sie Ihre eigenen Bibliotheken schreiben, sollten Sie nicht erwarten, dass die Anrufer natürlich Ausnahmen zu suchen denken zu fangen.

Die Konvention am weitesten verbreitete und verstanden ist, dass eines Delegierten, die einen Fehler Methode Rückruf hat, oder vielleicht Benachrichtigungen für allgemeinere Fehler, die Sie benötigen, um durch mehrere Ebenen von Code darauf zu verzichten. Dieser Ansatz könnte weiter verbreitet in der Java-Welt verwendet werden, wenn es ein einfaches Benachrichtigungssystem war die Art und Weise Cocoa hat es eingerichtet.

Der Delegierte Ansatz hat die gleiche Dokumentieren Eigenschaft als eine Ausnahme in Java erklärt hat, sind sie unterschiedliche Ansätze nur, aber es ist im Allgemeinen besser, einen Ansatz besser geeignet für die Sprache zur Hand zu benutzen, es sei denn es eine sehr zwingenden Grund ist es anders zu machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top