Question

Un de mes amis m'a demandé de ne pas utiliser NSException dans iPhone Apps. La raison pour laquelle il a été « goulot d'étranglement ». Mais je ne suis pas convaincu.

confirmer que quelqu'un peut me que nous devrions retenir d'utiliser NSException dans l'iPhone App? Si vous avez les meilleures pratiques pour l'utilisation NSException, s'il vous plaît fournir aussi.

Mise à jour:

lien nous demandes de l'utilisation gestion des exceptions au niveau de l'application. Demandez à quelqu'un jamais fait? S'il vous plaît donner les avantages de celui-ci et toute autre exécution Attelages pourrait créer.

Était-ce utile?

La solution

En bref:

Ne pas utiliser les exceptions pour indiquer les erreurs de quoi que ce soit, mais irrécupérables

Il est approprié que l'utilisation @ essayer / @ prises pour faire face à des erreurs irrécupérables. Il est jamais approprié d'utiliser @ jeter / @ try / catch pour faire @ flux de contrôle comme des opérations sur iOS ou Mac OS X. Même alors, Réfléchissez bien mieux d'utiliser une exception pour indiquer une erreur irrécupérable ou simplement écraser ( appeler abort ()); un accident souvent laisse derrière lui beaucoup plus de preuves.

Par exemple, il ne serait pas approprié d'utiliser pour la capture hors des limites du terrain exceptions à moins que votre objectif est de les attraper et en quelque sorte signaler l'erreur, alors - en général - accident ou, au moins, avertir l'utilisateur que votre application est dans un état incohérent et peut perdre des données.

Comportement d'exception jeté par le code-cadre du système est défini.


  

Pouvez-vous expliquer le « comportement de tout   exception levée par le système   Code-cadre est défini. » dans   détail?

Bien sûr.

Les cadres du système utilisent une conception où une exception est considérée comme une fatale, non récupérable, l'erreur; une erreur de programmation, pour toutes fins utiles. Il y a un nombre très limité d'exceptions (heh) à cette règle.

Ainsi, dans leur mise en œuvre, les cadres du système ne garantira pas que tout est nécessairement correctement nettoyé si une exception est lancée qui passe par un code-cadre du système. Sine l'exception est, par définition, irrécupérables, pourquoi payer les frais de nettoyage?

Considérez cette pile d'appel:

your-code-1()
    system-code()
        your-code-2()

i.e.. code où vos appels de code dans le code du système qui remet en plus de votre code (un modèle très courant, bien que les piles d'appels sont évidemment beaucoup plus profond).

Si your-code-2 lève une exception, que les exceptions passe au-dessus system-code signifie que le comportement est indéfini; system-code peut ou ne peut pas laisser votre demande dans un non défini, potentiellement crashy ou données avec perte, état.

Ou, plus fortement. Vous ne pouvez pas lancer une exception dans your-code-2 avec l'espoir que vous pouvez capturer et manipuler dans your-code-1

Autres conseils

Je l'ai utilisé la gestion des exceptions pour mon application audio assez intensive avec aucun problème. Après avoir beaucoup lu et un peu de l'analyse comparative et l'analyse du démontage, je me suis venu à la conclusion controversée qu'il n'y a aucune raison de ne pas les utiliser (intelligemment) et beaucoup de raison de ne pas (pointer-pointeurs NSError, sans fin ... conditionals beurk!). La plupart de ce que les gens disent sur les forums est que répéter l'Apple Docs.

Je vais dans un peu de détails dans ce blog mais je vais décrire mes résultats ici:

Mythe 1: @ try / @ catch / @ est finalement trop cher (en termes de CPU)

Sur mon iPhone 4, lancer et attraper 1 million d'exceptions prend environ 8,5 secondes. Cela équivaut à environ 8,5 microsecondes seulement pour chacun. Cher dans votre fil CoreAudio en temps réel? Peut-être un peu (mais vous ne l'avait jamais jeter des exceptions il n'y aurait pas ??), mais un retard dans le 8.5μs UIAlert indiquant à l'utilisateur qu'il y avait un problème à l'ouverture de leur dossier, cela va être remarqué?

Mythe 2: Les blocs @try ont un coût sur 32bit iOS

Les docs d'Apple parlent de "blocs de @try à coût zéro sur 64bit " et que l'état 32 bits entraîne un coût. Un peu d'étalonnage et d'analyse désassemblage semble indiquer qu'il existe des blocs de @try à coût zéro sur iOS 32bit (processeur ARM) ainsi. Est-ce que Apple a voulu dire 32bit Intel

Mythe n ° 3: Il importe que des exceptions Jeté à travers des cadres de cacao sont Undefined

Oui, ils sont « non défini », mais qu'est-ce que tu fais jeter dans le cadre d'Apple de toute façon? Bien sûr Apple ne les gère pas pour vous. Le point entier de la mise en œuvre la gestion des exceptions pour les erreurs récupérables est de les traiter localement -. Tout simplement pas tout-monoligne « localement »

Un cas limite est ici avec des méthodes telles que NSObject:performSelectorOnMainThread:waitUntilDone:. Si le paramètre plus tard est OUI, cela agit comme une fonction synchrone dans ce cas, vous pourriez être pardonné pour attendre l'exception à la bulle à votre champ d'appel. Par exemple:

/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCThread
/////////////////////////////////////////////////////////////////////////

@interface l5CCThread : NSThread @end

@implementation l5CCThread

- (void)main
{
    @try {

        [self performSelectorOnMainThread:@selector(_throwsAnException) withObject:nil waitUntilDone:YES];

    } @catch (NSException *e) {
        NSLog(@"Exception caught!");
    }
}
- (void)_throwsAnException { @throw [NSException exceptionWithName:@"Exception" reason:@"" userInfo:nil]; }

@end

/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCAppDelegate
/////////////////////////////////////////////////////////////////////////

@implementation l5CCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    l5CCThread *thd = [[l5CCThread alloc] init];
    [thd start];

    return YES;
}
// ...

Dans ce cas, l'exception passerait « dans le cadre de cacao » (la boucle d'exécution du thread principal) manquant vos prises et s'écraser. Vous pouvez facilement contourner ce en utilisant la dispatch_synch de GCD et la mise en argument bloc de ce l'appel de méthode ainsi que toute la gestion des exceptions.

Pourquoi utiliser NSException est plus NSError de

Quiconque a déjà fait un travail dans l'un des cadres basés C-anciens comme Core Audio sait ce qu'est une corvée, il vérifie, la manipulation et les erreurs de déclaration. Le principal avantage @ essayer / @ prises et NSExceptions offre est de rendre votre code plus propre et plus facile à entretenir.

Disons que vous avez 5 lignes de code qui fonctionnent sur un fichier. Chacun peut jeter un, disons, 3 erreurs différentes (par exemple hors de l'espace disque, erreur de lecture, etc.). Au lieu d'envelopper chaque ligne dans une condition qui vérifie une valeur de retour NO et externalise puis l'enquête de pointeur NSError à une autre méthode ObjC (ou pire, utilise une macro #define!), Vous enveloppez les 5 lignes dans un @try et gérer chaque erreur là. Pensez aux lignes que vous économisez!

En créant des sous-classes NSException, vous pouvez facilement Centraliser les messages d'erreur et éviter d'avoir votre code jonché avec eux. Vous pouvez également distinguer facilement « non mortelles » de votre application exceptions d'erreurs de programmeur mortels (comme NSAssert). Vous pouvez également éviter la nécessité de la constante « name » (nom de la sous-classe, est le « nom »).

Des exemples de tout cela et plus de détails sur les points de repère et de démontage sont sur ce blog ...

Exceptions, plus try / catch / finally estle paradigme utilisé par à peu près toutes les autres langues principales (C ++, Java, PHP, Ruby, Python). Peut-être que son temps de laisser tomber la paranoïa et l'embrasser et ... au moins dans iOS.

En général, demandez-vous si vous essayez de signaler une erreur, ou avez-vous fait une condition exceptionnelle? Si l'ancien, il est une très mauvaise idée, indépendamment de toute question de performance, réelle ou perçue. Dans ce dernier cas, il est très certainement la bonne chose à faire.

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