Lors du portage du code Java pour ObjC, la meilleure façon de représenter des exceptions vérifiés?

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

Question

Je travaille sur le portage de Java à base de code Cocoa / Objective-C pour une utilisation sur le bureau Mac OS X. Le code Java a beaucoup et beaucoup de méthodes avec vérification exceptions comme:

double asNumber() throws FooException {
    ...
}

Quelle est la meilleure façon de représenter dans Objective-C? Exceptions ou erreur out-paramètres?

- (CGFloat)asNumber { 
    ... // possibly [FooException raise:format:];
}

ou

- (CGFloat)asNumberError:(NSError **)outError {
    ...
}

Je sens que hors des erreurs sont généralement la meilleure solution pour Objective-C, mais comme vous pouvez le voir ... beaucoup de méthodes comme celle-ci sera assez maladroit prospectifs. Et encore, il y a beaucoup de ceux-ci.

Bien sûr garder à l'esprit que, puisque ceux-ci sont coché exceptions en Java, je vais avoir besoin d'ajouter soit des blocs de @try ou vérifie if (*outError) {...} chaque fois que ces méthodes sont appelées ( beaucoup de endroits).

Je me souviens avoir entendu que lors de la saisie des blocs de @try était autrefois cher en Objective-C, il est pas cher en 64 bits ou SL ou d'une autre nouvelle env (ne me souviens pas exactement). Je ne suis pas du tout préoccupé par la compatibilité ascendante, donc je suis définitivement prêt à concevoir que pour la nouvelle hotness.

Était-ce utile?

La solution

Vous devez éviter certainement des exceptions pour des choses comme les numéros de chaînes analyse syntaxique. En Objective-C, des exceptions représentent l'erreur de programmation, pas d'erreur d'entrée de l'utilisateur, ou même des fichiers indisponibles. (Une partie de la raison est que la gestion des exceptions est toujours plus coûteuse et plus complexe que la gestion des erreurs plus « classique ». Indépendamment du fait que entrer dans des blocs de @try est « zéro coût » 64 bits, il est lent encore chaque fois qu'une exception est en fait soulevée. ) Bien sûr, vous êtes autorisé à utiliser les exceptions que vous le souhaitez, mais ce n'est pas la façon dont le cacao et vous vous trouvez en désaccord avec tout autre code Objective-C. Les personnes qui utilisent votre code sera très ennuyé que vous jetez des exceptions dans les cas qui devraient simplement se traduire par une erreur.

De propres documents d'Apple :

  

"Dans de nombreux environnements, l'utilisation des exceptions est assez courante. Par exemple, vous pouvez lancer une exception pour signaler qu'une routine ne pouvait pas exécuter normalement comme lorsqu'un fichier est manquant ou des données ne peut pas être analysé correctement . les exceptions sont que vous ne devriez pas utiliser beaucoup de ressources en Objective-C. exceptions pour le flux général de contrôle, ou tout simplement pour signifier des erreurs. au lieu de cela, vous devez utiliser la valeur de retour d'une méthode ou d'une fonction pour indiquer qu'une erreur est survenue, et de fournir informations sur le problème dans un objet d'erreur. "

Regardez comment intégré dans les classes Cocoa gérer les erreurs comme celle-ci. Par exemple, NSString a des méthodes comme -floatValue qui renvoient 0 si il échoue. Une meilleure solution pour votre situation particulière pourrait être COMMEnT NSScanner elle, comme dans -scanFloat: -. accepter un pointeur vers le champ où le résultat doit être stocké, et le retour YES ou NO selon que l'analyse a été effectuée

En dehors de la convention Obejctive-C et les meilleures pratiques, NSError est beaucoup plus robuste et souple que NSException, et permet à l'appelant d'ignorer efficacement le problème si elles veulent. Je vous suggère de lire à travers le Gestion des erreurs Guide de programmation Cocoa . Remarque: Si vous acceptez un param NSError**, je vous suggère fortement concevoir également pour permettre au client de passer NULL si elles ne veulent pas recevoir des informations d'erreur. Chaque classe de cacao Je connais le fait pour des erreurs, y compris NSString.

Bien que le code peut portage finir par totalement différent du code Java, reconnaître qu'il sera utilisé par du code Objective-C, pas les mêmes clients de l'équivalent Java. correspondront certainement les idiomes de la langue. Le port ne sera pas une image miroir du code Java, mais il sera beaucoup plus correct (Objective-C) en conséquence.

Autres conseils

En Cocoa, des exceptions sont vraiment seulement censés être utilisés pour « erreurs de programmation; » la philosophie est de laisser l'application les attraper, donner à l'utilisateur la possibilité d'enregistrer ce qu'ils font, et cesser de fumer. D'une part, tous les cadres ou les chemins de code peuvent être 100% exception de sécurité, donc cela peut être le seul moyen d'action pour la sécurité. Pour les erreurs qui peuvent être anticipés et récupérés à partir, vous devez utiliser NSError, généralement au moyen d'un hors-paramètre.

Vous avez raison que « les erreurs sont généralement sur la meilleure solution pour ObjC ». Très rarement vous trouverez une API Cocoa qui lance une exception (à moins que vous ne l'avez pas satisfait aux conditions de l'API, mais dans ce cas, le comportement est non défini par défaut).

Si vous vous attendez à ce code à vivre au-delà de vous et être adopté par d'autres développeurs Cocoa, je vous conseille d'utiliser des erreurs. Je travaille sur le code qui a été construit par des gens qui ne connaissent pas de cacao et qui ont utilisé des exceptions généreusement, et ils sont une douleur royale de travailler autour.

Je suis un grand fan de l'approche d'erreur que utilise Objective-C. Vous devez gérer les exceptions, mais vous pouvez choisir d'ignorer les erreurs si vous voulez. Tout correspond à l'attitude Objective-C que « le programmeur sait ce qu'ils font. » Il fait également Objective-C un langage très propre avenir, parce que votre code n'est pas encombré de blocs try-catch.

Cela dit - vous pouvez envisager: Y a-t-il des scénarios où les exceptions sont ignorés? Les exceptions que vous jetez vraiment critiques ? Avez-vous vous retrouvez à écrire des blocs catch simples qui nettoient les variables et continuer? Je penche vers des erreurs parce que j'aime la syntaxe et les réserves Objective-C exceptions pour que les erreurs les plus critiques.

Ses ressemble à ces exceptions vérifiées plus proprement carte à des erreurs. Des exceptions pourraient encore être utilisés, mais doivent être réservés à des circonstances exceptionnelles.

Les exceptions sont probablement la meilleure approche, comme l'Obj-C ABI 64 bits (runtime) utilise zéro exceptions de coûts, de sorte que vous obtenez un code plus propre sans coût réel. Bien sûr, en 32 bits l'ancien setjmp / exceptions longjmp sont encore en cours d'utilisation et ne pas interagir avec C ++, donc si c'est un objectif, alors vous avez un problème.

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