9 Stimmen

Unter welchen Umständen ist @finally in Cocoa's try/catch/finally-Ausnahmebehandlung nicht redundant?

Betrachten Sie die folgenden Cocoa/Obj-C-Codefragmente:

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

y

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

Unter welchen Umständen führt das erste Snippet zu [obj cleanUp] aufgerufen wird, während die zweite wird nicht zur Folge haben [obj cleanUp] angerufen werden? Mit anderen Worten, unter welchen Umständen ist @finally nicht redundant bei der Verwendung von Cocoa Exception Handling?

15voto

dstnbrkr Punkte 4265

In diesen Szenarien gibt es keinen Unterschied, da die Ausnahme verschluckt wird. Hier sind zwei Szenarien, in denen es ist einen Unterschied:

[obj cleanUp] wird aufgerufen:

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

[obj cleanUp] wird nicht aufgerufen:

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

7voto

s4y Punkte 48459

Es ist auch erwähnenswert, dass der Code in @finally Blöcke werden ausgeführt, wenn die Kontrolle die @try Block aus irgendeinem Grund auch über return o goto . Zum Beispiel:

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

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

5voto

Jens Ayton Punkte 14459

In diesem Fall, in dem Sie die Ausnahme unterdrücken, keine. @finally wird verwendet, um aufzuräumen, wenn Sie entweder die Ausnahme nicht abfangen oder sie erneut auslösen, wobei in beiden Fällen die endgültige Antwort auf die Ausnahme dem aufrufenden Code überlassen wird. Da Ausnahmen in Cocoa nur für Programmierfehler verwendet werden sollen und daher selten auftreten, ist dies eine völlig vernünftige Sache.

Es sei auch auf einen Fall hingewiesen, in dem Sie nicht verwenden müssen @finally Sie richten dann Ihren eigenen Pool für die automatische Freigabe ein. Wenn der "übergeordnete" Autofreigabe-Pool zerstört wird, werden alle inneren Pools, die noch nicht bereinigt wurden, ebenfalls zerstört. Wenn Sie versuchen, sie selbst zu bereinigen, müssen Sie die Ausnahme selbst aus Ihrem Autorelease-Pool herausnehmen.

1voto

eglasius Punkte 35447

Wann:

  • Sie fangen die Art der Ausnahme nicht ab, die aufgetreten ist
  • Sie haben die Ausnahme abgefangen, aber der Code im Catch-Block löst ebenfalls eine Ausnahme aus.

0voto

Eine weniger wichtige Frage: Warum tun Sie das?

Der try/catch/finally-Ansatz ist in Java weit verbreitet, wird aber in Objective-C kaum verwendet und ist kein bevorzugter Ansatz - Sie brauchen ihn einfach nicht, da Bibliotheken keine Ausnahmen auslösen, wie es bei Java-Bibliotheksaufrufen der Fall wäre, und wenn Sie Ihre eigenen Bibliotheken schreiben, sollten Sie nicht erwarten, dass der Aufrufer von sich aus nach Ausnahmen zum Abfangen sucht.

Die Konvention, die am weitesten verbreitet ist und verstanden wird, ist die eines Delegaten, der einen Rückruf der Fehlermethode hat, oder vielleicht Benachrichtigungen für allgemeinere Fehler, die Sie durch mehrere Codeebenen weiterleiten müssen. Dieser Ansatz könnte in der Java-Welt weiter verbreitet sein, wenn es ein einfaches Benachrichtigungssystem gäbe, so wie es in Cocoa eingerichtet ist.

Der Delegate-Ansatz hat die gleiche dokumentierende Eigenschaft wie die Deklaration einer Exception in Java, es sind nur unterschiedliche Ansätze, aber es ist im Allgemeinen besser, einen Ansatz zu verwenden, der besser für die jeweilige Sprache geeignet ist, es sei denn, es gibt einen sehr zwingenden Grund, etwas anderes zu tun.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X