Question

Je suis depuis longtemps développeur Microsoft et je suis nouveau sur le développement iPhone en utilisant Xcode. Donc, je suis en train de lire un livre et passer par des exemples en essayant de me apprendre à écrire une application iPhone en utilisant Objective-C. Tout a été bon jusqu'à présent, cependant, de temps en temps je lance dans le message « objc_exception_throw » générique lors de l'exécution. Lorsque cela se produit, la source de cette exception est très difficile à trouver. Après quelques essais et erreurs, j'ai trouvé ma réponse. L'un des paramètres a été mal orthographié.

Comme vous pouvez le voir ci-dessous, je mal orthographié le paramètre « otherButtonTitles » en laissant la seconde « t » en bouton.

UIAlertView *alert = [[UIAlertView alloc] 
                      initWithTitle:@"Date and Time Selected" 
                      message:message 
                      delegate:nil
                      cancelButtonTitle:@"Cancel"
                      otherButonTitles:nil];

La raison pour laquelle cela m'a pris du temps pour trouver est que le code construit avec succès. Est-ce normal pour le compilateur Objective-C? Je suis habitué à avoir la construction échouent dans le compilateur .NET quand je fais une erreur de syntaxe commune comme celui-ci. Est-il un paramètre du compilateur je peux changer pour faire échouer le haut quand je fais ces erreurs?

Était-ce utile?

La solution

D'abord et avant tout, ~/.gdbinit ouvert (c'est le fichier appelé .gdbinit dans votre répertoire personnel - oui, commence par un point) et mettre cela en elle:

fb -[NSException raise]
fb objc_exception_throw
fb malloc_error_break

Ça va initialize GDB avec trois points d'arrêt par défaut, quand ils se produisent, GDB arrêtera votre application et vous montrer la trace de la pile. Ceci est très bien intégré à Xcode afin que vous serez capable de marcher bien dans votre code en cliquant sur les oligo-éléments de la pile dès qu'une exception se produit quelque part ou malloc échoue.

Ensuite, ouvrez le panneau Get Info sur votre projet (ou sélectionnez votre projet (point haut dans le Groups & Files) et appuyez sur cmd-i), allez dans l'onglet Build et définir la Base SDK de votre projet Device - iPhone OS [someversion]. Faites défiler la liste vers le bas et trouver la section GCC 4.0 - Warnings. Là; allumer autant de mises en garde que vous vous sentez à l'aise, mais assurez-vous d'allumer Treat Warnings as Errors (ce qui est l'équivalent de GCC_TREAT_WARNINGS_AS_ERRORS). Personnellement, je l'ai mis à ceci:


(source: lyndir.com )

Vous devriez maintenant être obtenir les avertissements du compilateur pour la plupart des choses que vous pouvez faire mal dans le code et le compilateur ne vous laissera pas exécuter le code jusqu'à ce que vous les corriger. Quand les choses ne se passé le nez du compilateur, vous devriez être en mesure de trouver le problème facilement avec la rupture GDB à un endroit pratique.

Vous devriez également se pencher sur NSZombie*. Ce sont des variables d'environnement qui sont très pratique pour rupture anticipée sur les mauvaises situations d'allocation ou accès mémoire. Par exemple; wih rien NSZombieEnabled va vraiment être libéré; sur dealloc il va être écrasé avec _NSZombie et si vous essayez d'accéder à cette mémoire dealloced à nouveau (déréférencement d'un pointeur dealloced) vous aurez quelque chose à briser dans GDB, au lieu de l'appel en passant par comme d'habitude, n'émis sur au hasard les données (qui, bien sûr, n'est pas ce que vous vouliez). Pour plus d'informations sur ce sujet, consultez http://www.cocoadev.com/index.pl?NSZombieEnabled .

Autres conseils

Utilisez toujours le réglage du GCC -Werror (de GCC_TREAT_WARNINGS_AS_ERRORS = YES). Vous ne devriez jamais avoir des avertissements dans votre code et ceci est un exemple où l'avertissement est une erreur critique.

En outre, si vous obtenez un objc_exception_throw, passer à la console (Commande-Maj-R) et recherchez la première adresse du numéro « faible ».

2009-04-01 13:25:43.385 CrashExample[41720:20b] Stack: (
    2528013804,
    2478503148,
    2528036920,
    2528053460,
    2358032430,
    11076,
    11880,
    816174880,
    345098340,
    145973440,
    816174880,
)

Dans ce cas, il serait « 11076 ». Donc, tapez dans la console:

info line *11076

Cela vous dire la ligne dans votre code où l'exception a été levée.

paramètres Misspelled devraient généralement dans un « Avertissement: tel ou tel objet ne répond pas au sélecteur x » en jaune sur la ligne en question. Je crois que c'est par défaut, comme je ne devais pas modifier les paramètres du compilateur pour voir ceux-ci.

En outre, quand je rencontre une exception non détectée, il est parfois bénéfique de tomber dans la console de GDB (devrait apparaître lorsque vous exécutez votre application) et tapez ce qui suit pour obtenir backtraces pour toutes les discussions:

t a un bt

Qu'est-ce que vous avez fait est pas une erreur de compilation, parce que les contrôles d'exécution Objective-C lors de l'exécution si un objet peut répondre au message que vous lui envoyez.

Je recommande l'ajout de cette version mise à votre cible ou d'un projet:

GCC_TREAT_WARNINGS_AS_ERRORS = YES

La raison pour laquelle ce n'est pas une erreur de compilation, est parce qu'il est parfaitement valable d'envoyer un message non connu au moment de la compilation à tout objet (et tout objet peut être configuré pour gérer les messages dynamiquement aussi bien). Tous les appels de méthode sont vraiment des messages envoyés à des objets.

En général, si vous voyez des avertissements que vous devez les traiter, comme dans la plupart des cas, ils peuvent conduire à des problèmes (comme vous l'avez vu). L'aspect trompeur est ici est que si vous compilez un fichier une fois et il n'a que des avertissements, si vous compilez d'autres classes sans apporter de modifications à la classe qui a des avertissements, l'avertissement ne sera pas affiché dans les messages du compilateur. Donc, chaque maintenant et vous voudrez peut-être « nettoyer toutes les cibles » et de construire à nouveau pour vous assurer que vous ne manquez aucun avertissement.

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