Unter welchen Umständen ist @finally nichtredundanten in Cocoa try / catch / finally Exception Handling?
-
09-09-2019 - |
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?
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.