Le problème strong> J'écris une application de cacao et je souhaite soulever des exceptions qui placera l'application bruyamment. p> J'ai les lignes suivantes dans mon application Délégué: p> -(void)applicationDidFinishLaunching:(NSNotification *)note
// ...
[self performSelectorInBackground:@selector(crash) withObject:nil];
}
-(void)crash {
[NSException raise:NSInternalInconsistencyException format:@"This should crash the application."];
abort();
}
6 Réponses :
J'ai posté cette question et répondez comme je la souhaite que quelqu'un m'aurait dit cela, oh il y a environ un an: p>
I Skim Lisez les docs sur NsException Fin à la fin, sans mentionner cela que je peux me rappeler. La seule raison pour laquelle je sais cela est à cause du fantastique cacao dev: p>
http://www.cocoadev.com/index.pl?ExceptionHandling p>
J'ai un démon sans interface utilisateur qui fonctionne presque entièrement sur le fil principal. Je devrai transférer l'application entière pour exécuter des threads d'arrière-plan, à moins que quelqu'un d'autre ne puisse suggérer un moyen d'arrêter Nsaplication capturer uniquement les exceptions que je jette. Je suis à peu près sûr que ce n'est pas possible. P>
Je pense que vous avez manqué une page. développeur.apple.com/mac/library/documentation/cocoa/conceptu al / ... " Remarque: Les exceptions sur le fil principal d'une application de cacao n'augmentent généralement pas au niveau du gestionnaire d'exceptions non capturies car L'objet d'application global attrape toutes ces exceptions. " ... Le corps principal de la page mentionne également la solution David Gelhar a parlé de.
Oui, évidemment très paresseux, lecture de ma part. :) Merci d'avoir souligné cela. Il y a même une boîte autour de le souligner. Duh.
Bonjour John, j'ai posté une "réponse" ci-dessous dans une tentative de comprendre le problème plus clairement. Des idées?
Peu importe, je pense que j'ai trouvé une solution à mon problème. J'ai mis à jour ma "réponse" en conséquence.
Peut-être que vous pouvez utiliser NSSETUNTERDEXCEPTHANDLER ou Créez une catégorie sur NSApplication qui remplace - ReportException: , comme suggéré à http://www.cocoadev.com/index.ploStackTraces P>
Excellente suggestion, David. J'ai lu cette page des lots il y a quelques mois, mais je n'ai pas essayé la catégorie de catégorie Nsappllication pour une raison quelconque. J'aurai un coup de travail de cette façon, car il est beaucoup plus facile que d'essayer d'obtenir tout mon code en cours d'exécution sur les threads de fond!
Comment peut-on J'arrête Hitoolbox d'attraper mes exceptions? p> Ceci se développe sur David Gelhar's Strong> réponse, et le lien qu'il a fourni. Vous trouverez ci-dessous la façon dont je l'ai fait en remplaçant la méthode NsApplication + ExceptionnelHandling.h fort> p> nsappllication + exceptionsHandling.m strong> p> second, à l'intérieur Délégué de Nsapplication, j'ai procédé à ce qui suit: p> plutôt que d'utiliser le Chaque fois qu'une exception est lancée, sur le fil principal em>, et que ce n'est pas attrapé ni détruit, votre Le gestionnaire d'exception personnalisé non capturé sera désormais appelé à la place des NSAPPLICATION. Cela vous permet de planter votre application, entre autres choses. P> Il semble y avoir un petit problème dans le code ci-dessus. Votre gestionnaire d'exception personnalisé ne «frappera» et ne fonctionnera qu'après que Nsaplication ait fini d'appeler toutes ses méthodes de délégation. Cela signifie que si vous faites du code de configuration à l'intérieur Qu'est-ce que cela signifie que c'est si vous faites ceci: p> Votre exceptionnel (forte> won ' t obtenir l'exception. Nsapplication va, et ça va simplement le loger. P> Pour résoudre ce problème, mettez simplement tout code d'initialisation à l'intérieur d'un
-ReportException de NSAPPLication: code>. Premièrement, créez une catégorie d'exceptions pour NSApplication (FYI, vous devez ajouter un acronyme de 2 à 3 lettres avant «Exceptions de l'exception» pour réduire le risque d'afflichage de noms): P>
NSAPP's Terminez: , vous pouvez appeler
quitter () code> à la place.
Terminez: CODE> est plus cocoa-casher, bien que vous puissiez ignorer votre
ApplicationsHouldterminate: code> dans l'événement Une exception a été lancée et simplement un crash difficile avec
Quitter ( ) code>: p>
Mise à jour: strong> h2>
@ try / @ catch / @ enfin code> bloquer et vous pouvez appeler votre Personnalisé ExceptionnelHandler STROND>: P>
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
NSSetUncaughtExceptionHandler(&exceptionHandler);
@try
{
MyClass *myClass = [[MyClass alloc] init]; // throws an exception during init...
}
@catch (NSException * e)
{
exceptionHandler(e);
}
@finally
{
// cleanup code...
}
}
Cette solution est trop complexe. La réponse de George ci-dessous est la bonne façon de le faire: "[[[Nsuserdefault StandardAserdefault] registerDefault
Je suis en train de comprendre cela: Pourquoi la méthode de la catégorie suivante sur NSApplication conduire à une boucle infinie? Dans cette boucle infinie, « Une exception uncaught élevée » est connecté à l'infini plusieurs fois:
- (void)reportException:(NSException *)anException { // handle the exception properly (*NSGetUncaughtExceptionHandler())(anException); }
Il s'avère être une solution très simple: p>
Il fait pas fort> Crash votre application si vous utilisez Je ne peux pas commencer à imaginer pourquoi ce n'est pas la valeur par défaut. P> [[NSUserDefaults StandardDeFaultS] registerDefaults: @ {@ "Nsapplicationcrashononceptions": @yes}]; Code> P>
@try ... @catch code>. p>
Notez que cela ne frappe qu'après que Nsaplication ait fini d'appeler toutes ses méthodes de délégation.
En fait, c'est pire que ça. Cela ne fonctionne pas dans aucun code de manutention AppleEvent. Voir la réponse ci-dessous pour la solution de contournement.
Il s'agit de la raison pour laquelle il apparaît que le gestionnaire d'exception n'appelle pas appelé vos méthodes de déléguée d'application est que Donc, mon "correction" pour cela: p> FUN EXTRA Remarque: la version par défaut dans le _nsappleeventmanagergergenerglandLandler code> (une API privée) a un
@try Code>
@catch code> bloc qui attrape toutes les exceptions et appelez simplement NSLog sur eux avant de retourner avec un
erraeeventnothandled code> oserr. Cela signifie que non seulement vous allez manquer toutes les exceptions dans l'application Start Up, mais essentiellement des exceptions qui se produisent à l'intérieur de la manipulation d'un AppleEvent qui inclut (mais ne se limite pas à) les documents d'ouverture, l'impression, l'abandon et tout AppleScript.
nslog (@ "% @", exception) code> équivaut à
NSLOG (@ "% @", exception.Reason) code>.
NSLOG (@ "% @", [EXCEPTION DEBUGDEDESCRIPTION]) CODE> Vous donnera la raison plus la pile de pile entièrement symbolisée. p>
_nsappleeventmanagergergenergénherkandler Code> juste appelle
nslog (@ "% @", exception) code> (MacOS 10.14.4 (18E226)) P> P>
Radar Filtré 50933952 - [NsappleeventManager] Veuillez effectuer une meilleure exploitation d'exception CODE> et RADAR 50933868 -
NsappleeventManager doit respecter les paramètres de manutention des exceptions code>
Je devrais également noter que mon correctif ci-dessus modifiera la manière dont les Appleevents interagissent avec votre application, mais uniquement dans le cas où une exception est lancée. Sans le correctif, votre application reviendra une errappleEventNothandled et continuera à tenter de boiter, potentiellement dans un état corrompu. Avec mon correctif, l'application s'écrasera et que celui-ci a appelé que vous obtiendrez une erreur ConnectionInvalid.