Dans quelles circonstances est @finally non redondant dans try / catch / finally la gestion des exceptions de cacao?

StackOverflow https://stackoverflow.com/questions/741555

Question

Considérez les extraits suivants de cacao / code Obj-C:

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

et

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

Dans quelles circonstances le premier résultat de bout en [obj cleanUp] appelé, tandis que le second pas entraîner [obj cleanUp] être appelé? En d'autres termes, dans quelles circonstances est @finally non redondant lors de l'utilisation Gestion des exceptions Cocoa?

Était-ce utile?

La solution

Dans ce cas, vous êtes l'exception squashing, aucun. @finally est utilisé pour nettoyer lorsque vous ne soit pas attraper l'exception, ou réémettre il, dans les deux cas laissant réponse d'exception finale au code d'appel. Étant donné que les exceptions à Cocoa ne sont censés être utilisés pour les erreurs de programmation et donc se produisent rarement, cela est une chose tout à fait raisonnable de le faire.

Il est également utile de rappeler un cas où vous ne pas besoin d'utiliser @finally, qui est lorsque vous configurez votre propre piscine autorelease. Lorsque la piscine autorelease « parent » est détruit, tout les internes qui n'ont pas encore été nettoyés seront également. Si vous essayez de le nettoyer vous-même, vous devez promouvoir l'exception se de votre piscine autorelease.

Autres conseils

Dans ces scénarios, il n'y a pas de différence, car l'exception est avalée. Voici deux scénarios où une différence:

[obj cleanUp] est appelé:

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

[obj cleanUp] n'est pas appelé:

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

Il est également intéressant de noter que le code dans des blocs de @finally fonctionnera lorsque le contrôle quitte le bloc @try pour quelque raison que , même via return ou goto. Par exemple:

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

[obj cleanUp] exécutera même si bail est vrai, mais [obj announceSuccess] ne sera pas.

  • Vous ne rattrapent pas le type d'exception qui a eu lieu
  • Vous avez attrapé l'exception, mais le code dans le bloc catch soulève également une exception.

Une question de niveau inférieur, pourquoi fais-tu cela?

Le try / catch / finally approche est largement utilisée en Java, mais presque jamais utilisé en Objective-C, et n'est pas une approche préférée - vous ne tout simplement pas besoin que les bibliothèques ne jetteront pas des exceptions le traitement des appels de bibliothèque Java serait, et si vous écrivez vous ne devriez pas attendre vos propres bibliothèques appelants penseront à regarder naturellement des exceptions à attraper.

La convention la plus largement utilisée et comprise est celle d'un délégué qui a un rappel de la méthode d'erreur, ou peut-être des notifications pour les échecs plus généraux que vous devez laisser passer à travers de multiples niveaux de code. Cette approche pourrait être plus largement utilisée dans le monde Java s'il y avait un système de notification simple la façon dont Cocoa l'a mis en place.

L'approche délégué a la même documentant la propriété en déclarant une exception en Java le fait, ils ne sont que des approches différentes, mais il est généralement préférable d'utiliser une approche plus adaptée à la langue à portée de main, à moins qu'il ya une raison très convaincante de faire autrement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top