2010-01-06 10 views
5

J'essaie d'utiliser NSAssert dans l'ensemble de mon application iPhone pour que, si une condition imprévue se produit, l'application échoue rapidement et se bloque avec un message significatif dans le journal de panne.Utilisation de NSAssert dans les threads

Cela fonctionne très bien si le NSAssert défaillant se trouve sur le thread principal, car il déclenche par défaut NSInternalInconsistencyException qui n'est pas intercepté et arrête l'exécution. Mais je fais aussi du traitement dans les threads d'arrière-plan, auquel cas le NSAssert abandonne juste le thread, mais la programmation continue de fonctionner.

Ma solution actuelle est d'attraper et réémettre l'exception dans le thread principal (dans ce cas, la méthode de mainNSOperation):

- (void)main { 
    @try { 
     int x = 14; 
     ... 
     NSAssert1(x > 20, @"x should be greater than 20, was %d", x); 
     ... 
    } 
    @catch (NSException *e) { 
     [e performSelectorOnMainThread:@selector(raise) withObject:nil waitUntilDone:YES]; 
    } 
} 

Y at-il une meilleure façon? Peut-être en utilisant un NSAssertionHandler personnalisé?

Je sais que je pourrais simplement utiliser C de assert avec une annotation statique:

assert(x > 20 && "x should be greater than 20"); 

Mais cela ne me permet pas de montrer ce que la valeur réelle de défaut est x.

+0

J'ai le même problème, mais la solution proposée ne fonctionnera pas pour moi. Le NSAssert est déclenché, le thread meurt, mais l'application continue à fonctionner. J'utilise le moteur Cocos2D. Quelqu'un pourrait-il fournir une solution plus complète? –

Répondre

1

Vous pouvez remplacer le NSAssert par un code de test suivi d'une exception. De cette façon, si l'assertion échoue, une exception sera levée, attrapée par le bloc @catch et sur-relancée sur le thread principal.

Remarque: Vous pouvez même définir une macro C afin de fournir une forme compacte.

+0

C'est ce que NSAssert fait par défaut - il soulève une exception NSInternalInconsistencyException. Donc, vous préconisez la solution catch/re-raise ci-dessus? – sickp

+0

J'ai relu la documentation et NSAssert soulève une exception. Donc, votre solution actuelle semble correcte. –