297 votes

Signal EXC_BAD_ACCESS reçu

Lors du déploiement de l'application sur le périphérique, le programme se ferme après quelques cycles avec l'erreur suivante:

Program received signal: "EXC_BAD_ACCESS".

Le programme fonctionne sans problème sur le simulateur d'iPhone, il sera également déboguer et courir aussi longtemps que j'ai pas à travers les instructions une à une. Dès que je l'ai laisser tourner encore une fois, je vais frapper l' EXC_BAD_ACCESS de signal.

Dans ce cas particulier, il est arrivé à être une erreur dans la accéléromètre code. Il ne serait pas exécuter dans le simulateur, c'est pourquoi il n'a pas de jeter des erreurs. Cependant, il exécute une fois déployé à l'appareil.

La plupart des réponses à cette question avec le général EXC_BAD_ACCESS erreur, donc je vais laisser cette ouverture comme un fourre-tout pour le redoutable Mauvaise erreur d'Accès.

EXC_BAD_ACCESS est généralement jeté comme le résultat d'un acte illégal d'accès à la mémoire. Vous pouvez trouver plus d'informations dans les réponses ci-dessous.

Avez-vous rencontré l' EXC_BAD_ACCESS signal avant, et comment avez-vous réagi?

201voto

philsquared Points 13547

À partir de votre description je soupçonne l'explication la plus probable est que vous avez une erreur dans votre gestion de la mémoire. Vous avez dit que vous avez travaillé sur le développement iPhone pour quelques semaines, mais pas de savoir si vous avez de l'expérience avec Objective-C en général. Si vous venez d'un autre contexte, il peut prendre un peu de temps avant de vraiment internaliser la gestion de la mémoire des règles, à moins de faire un gros point.

Rappelez-vous, tout ce que vous obtenez à partir d'une fonction d'allocation (généralement de la statique alloc méthode, mais il ya quelques autres), ou une méthode de copie, vous possédez la mémoire trop et doit le libérer lorsque vous avez terminé.

Mais si vous obtenez quelque chose en retour de tout ce que vous voulez , y compris l'usine de méthodes (par exemple, [NSString stringWithFormat]), alors vous aurez un autorelease de référence, ce qui signifie qu'il pourrait être libéré à un certain moment dans l'avenir par d'autres, il est essentiel que si vous avez besoin de le garder au-delà de la mise en fonction immédiate que vous le conserver. Si vous ne le faites pas, la mémoire peut rester affecté pendant que vous l'utilisez, ou d'être libérée mais comme par hasard toujours valide, au cours de votre émulateur de test, mais il est plus susceptible d'être libéré et de se présenter comme de mauvais accès à des erreurs lors de l'exécution sur le périphérique.

La meilleure façon de suivre ces choses, et de toute façon une bonne idée (même si il n'y a pas de problèmes apparents) est de lancer l'application dans les Instruments de l'outil, en particulier avec les Fuites option.

102voto

bentford Points 9981

L'une des principales causes de EXC_BAD_ACCESS est d'essayer d'accéder à objets publiés.

Pour savoir comment résoudre ce problème, la lecture de ce document: DebuggingAutoReleasePool

Même si vous ne pensez pas que vous êtes "la libération de l'auto-publié objets", cela va s'appliquer à vous.

Cette méthode fonctionne très bien. Je l'utilise tout le temps avec beaucoup de succès!!

En résumé, c'est ce qui explique comment utiliser du Cacao NSZombie de débogage de la classe et de la ligne de commande "malloc_history" outil pour trouver exactement ce que libéré de l'objet a été consultée dans votre code.

Sidenote:

L'exécution des Instruments et de la recherche de fuites ne seront pas vous aider à résoudre EXC_BAD_ACCESS. Je suis sûr que les fuites de mémoire n'ont rien à voir avec EXC_BAD_ACCESS. La définition d'une fuite est un objet que vous n'y avez plus accès, et, par conséquent, vous ne peut pas l'appeler.

Mise à JOUR: Je vais maintenant utiliser des Instruments pour déboguer les Fuites. À partir de Xcode 4.2, choisissez des Produits->Profil et lorsque les Instruments lance, choisissez "Zombies".

13voto

Adam Rosenfield Points 176408

Un EXC_BAD_ACCESS signal est le résultat du passage d'un pointeur non valide à un appel système. J'en ai une, plus tôt aujourd'hui avec un programme de test sur OS X, j'ai été en passant une variable non initialisée à l' pthread_join(), ce qui était dû à un état antérieur de la faute de frappe.

Je ne suis pas familier avec le développement sur iPhone, mais vous devriez vérifier tous vos pointeurs de tampon que vous êtes de passage à des appels système. Monter votre niveau d'avertissement du compilateur (gcc, utilisez l' -Wall et -Wextra des options). Permettre au plus grand nombre de diagnostics sur le simulateur/débogueur que possible.

8voto

Brent Royal-Gordon Points 8044

Dans mon expérience, cela est généralement causé par un acte illégal d'accès à la mémoire. Vérifier tous les pointeurs, en particulier les pointeurs d'objet, afin de s'assurer qu'ils sont initialisés. Assurez-vous que votre MainWindow.xib fichier, si vous en utilisez un, est mis en place correctement, avec toutes les connexions nécessaires.

Si rien de tout cela sur le papier la vérification de tours quoi que ce soit, et il ne se produit pas lorsque le mode pas à pas, essayez de localiser l'erreur avec NSLog() déclarations: saupoudrez votre code avec eux, de les déplacer jusqu'à ce que vous isoler la ligne qui est la cause de l'erreur. Ensuite, définissez un point d'arrêt sur cette ligne et exécuter votre programme. Quand vous frappez le point d'arrêt, d'examiner toutes les variables, et les objets en eux, pour voir si quelque chose ne fonctionne pas comme prévu.Je dirais surtout de garder un œil sur les variables dont la classe d'objet est quelque chose que vous ne vous attendiez pas. Si une variable est censé contenir un UIWindow mais il a un NSNotification dans ce lieu, le même code sous-jacent erreur peut se manifester d'une manière différente lorsque le débogueur n'est pas en fonctionnement.

6voto

Rob Points 1895

Pas une réponse complète, mais une situation particulière où j'ai reçu, c'est lorsque vous essayez d'accéder à un objet qui "meurt" parce que j'ai essayé d'utiliser autorelease:

netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];

Ainsi, par exemple, j'étais en fait passer cela comme un objet de notifier (enregistré en tant qu'auditeur, observateur, quel que soit l'idiome vous le souhaitez), mais il était déjà mort une fois que la notification a été adressée, et je serais le EXC_BAD_ACCESS. Changer l' [[MyNetObject alloc] init] , et en la relâchant, plus tard, comme approprié résolu l'erreur.

Une autre raison de ce qui peut arriver par exemple si vous passez un objet et d'essayer de les stocker:

myObjectDefinedInHeader = aParameterObjectPassedIn;

Plus tard, lorsque j'essaie d'accéder myObjectDefinedInHeader vous pouvez avoir des ennuis. À l'aide de:

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

peut-être ce dont vous avez besoin. Bien sûr, ce sont juste quelques exemples de ce que j'ai couru dans et il y a d'autres raisons, mais ils peuvent s'avérer insaisissable pour que je le mentionne. Bonne chance!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X