Ao implantar o aplicativo no dispositivo, o programa será encerrado após alguns ciclos com o seguinte erro:
Program received signal: "EXC_BAD_ACCESS".
O programa é executado sem nenhum problema no simulador do iPhone, ele também irá depurar e executar desde que eu siga as instruções, uma de cada vez. Assim que eu deixá-lo funcionar novamente, atingirei o EXC_BAD_ACCESS
sinal.
Nesse caso em particular, ocorreu um erro no código do acelerômetro. Não seria executado dentro do simulador, razão pela qual não gerou nenhum erro. No entanto, ele seria executado uma vez implantado no dispositivo.
A maioria das respostas para esta pergunta lida com o EXC_BAD_ACCESS
erro geral , por isso deixarei em aberto como um exemplo para o temido erro de mau acesso.
EXC_BAD_ACCESS
normalmente é lançado como resultado de um acesso ilegal à memória. Você pode encontrar mais informações nas respostas abaixo.
Você já encontrou o EXC_BAD_ACCESS
sinal antes e como lidou com isso?
fonte
Uma das principais causas de EXC_BAD_ACCESS é a tentativa de acessar objetos liberados.
Para descobrir como solucionar isso, leia este documento: DebuggingAutoReleasePool
Mesmo que você não ache que está "liberando objetos liberados automaticamente", isso se aplicará a você.
Este método funciona extremamente bem. Eu uso o tempo todo com grande sucesso !!
Em resumo, isso explica como usar a classe de depuração NSZombie do Cocoa e a ferramenta "malloc_history" da linha de comando para encontrar exatamente qual objeto liberado foi acessado no seu código.
Nota:
A execução de instrumentos e a verificação de vazamentos não ajudarão a solucionar problemas de EXC_BAD_ACCESS. Tenho certeza de que vazamentos de memória não têm nada a ver com EXC_BAD_ACCESS. A definição de vazamento é um objeto ao qual você não tem mais acesso e, portanto, não pode chamá-lo.
ATUALIZAÇÃO: Agora eu uso instrumentos para depurar vazamentos. No Xcode 4.2, escolha Produto-> Perfil e, quando o Instruments for iniciado, escolha "Zombies".
fonte
Um sinal EXC_BAD_ACCESS é o resultado da passagem de um ponteiro inválido para uma chamada do sistema. Consegui um hoje cedo com um programa de teste no OS X - eu estava passando uma variável não inicializada
pthread_join()
, devido a um erro de digitação anterior.Não estou familiarizado com o desenvolvimento do iPhone, mas verifique todos os ponteiros de buffer que está passando para as chamadas do sistema. Aumente o nível de aviso do seu compilador até o fim (com gcc, use as opções
-Wall
e-Wextra
). Habilite o maior número possível de diagnósticos no simulador / depurador.fonte
Na minha experiência, isso geralmente é causado por um acesso ilegal à memória. Verifique todos os ponteiros, especialmente os de objetos, para garantir que sejam inicializados. Verifique se o arquivo MainWindow.xib, se você estiver usando um, está configurado corretamente, com todas as conexões necessárias.
Se nenhuma dessas verificações no papel exibir alguma coisa e isso não acontecer ao executar uma etapa única, tente localizar o erro com as instruções NSLog (): espalhe seu código com elas, movendo-as até isolar a linha que está causando o erro. Em seguida, defina um ponto de interrupção nessa linha e execute seu programa. Quando você atinge o ponto de interrupção, examine todas as variáveis e os objetos nelas, para ver se algo não parece o esperado. Eu ficaria de olho nas variáveis cuja classe de objeto é algo que você não esperava. Se uma variável deve conter uma UIWindow, mas ela possui uma NSNotification, o mesmo erro de código subjacente pode estar se manifestando de maneira diferente quando o depurador não está em operação.
fonte
Passei algumas horas rastreando um EXC_BAD_ACCESS e encontrei o NSZombies e outros ambientes não pareciam me dizer nada.
Para mim, foi uma declaração estúpida do NSLog com especificadores de formato, mas nenhum argumento foi passado.
Corrigido por
fonte
Os vídeos da WWDC de 2010 estão disponíveis para todos os participantes do programa de desenvolvedores da apple. Há um ótimo vídeo: "Sessão 311 - Análise avançada de memória com instrumentos", que mostra alguns exemplos de uso de zumbis em instrumentos e depuração de outros problemas de memória.
Para um link para a página de login, clique AQUI .
fonte
Não é uma resposta completa, mas uma situação específica em que eu recebi isso é ao tentar acessar um objeto que 'morreu' porque tentei usar a liberação automática:
Por exemplo, eu estava passando isso como um objeto para 'notificar' (registrei como ouvinte, observador, qualquer idioma que você quiser), mas ele já havia morrido assim que a notificação foi enviada e eu recebi o EXC_BAD_ACCESS. Alterá-lo para
[[MyNetObject alloc] init]
e liberá-lo mais tarde, conforme apropriado, resolveu o erro.Outro motivo para isso acontecer é, por exemplo, se você passar um objeto e tentar armazená-lo:
Mais tarde, ao tentar acessar myObjectDefinedInHeader, você poderá ter problemas. Usando:
pode ser o que você precisa. É claro que esses são apenas alguns exemplos do que eu encontrei e há outras razões, mas elas podem ser ilusórias, então eu as mencionei. Boa sorte!
fonte
Apenas para adicionar outra situação em que isso pode acontecer:
Eu tinha o código:
Obviamente eu tinha esquecido de alocar memória para a string:
resolve o problema.
fonte
Outro método para capturar exceções EXC_BAD_ACCESS antes que elas ocorram é o analisador estático , no XCode 4+.
Execute o analisador estático com Produto> Analisar (shift + cmd + B). Clicar em qualquer mensagem gerada pelo analisador sobreporá um diagrama em sua fonte, mostrando a sequência de retenções / liberações do objeto incorreto.
fonte
Acho útil definir um ponto de interrupção em objc_exception_throw. Dessa forma, o depurador deve quebrar quando você obtém o EXC_BAD_ACCESS.
As instruções podem ser encontradas aqui Técnicas de depuração
fonte
Use a regra simples de "se você não a alocou ou reteve, não a solte".
fonte
Como depurar EXC_BAD_ACCESS
Confira o link acima e faça o que diz .... Apenas algumas instruções rápidas para usar o NSZombies
Execute o aplicativo e depois que ele falhar (deve exibir "Interrompido" em vez de "EXC_BAD_ACCESS" ... verifique o console (Executar> console)) ... deve haver uma mensagem lá agora informando qual objeto ele estava tentando acessar.
-Ben
fonte
Venho depurando e refatorando o código para solucionar esse erro nas últimas quatro horas. Uma postagem acima me levou a ver o problema:
Propriedade anterior: startPoint = [[DataPoint alocado] init]; startPoint = [DataPointList objectAtIndex: 0];
. . . x = startPoint.x - 10; // EXC_BAD_ACCESS
Propriedade após: startPoint = [[DataPoint alocado] init]; startPoint = [[DataPointList objectAtIndex: 0] reter];
Adeus EXC_BAD_ACCESS
fonte
Espero que você esteja liberando a 'corda' quando terminar!
fonte
Eu esqueci de retornar a si mesmo em um método init ...;)
fonte
Este é um excelente tópico. Aqui está minha experiência: eu errei com a palavra-chave reter / atribuir em uma declaração de propriedade. Eu disse:
onde eu deveria ter dito
fonte
Encontrei EXC_BAD_ACCESS no iPhone apenas enquanto tentava executar um método C que incluía uma grande matriz. O simulador conseguiu me fornecer memória suficiente para executar o código, mas não o dispositivo (o array tinha um milhão de caracteres, portanto, era um pouco excessivo!).
O EXC_BAD_ACCESS ocorreu logo após o ponto de entrada do método e me deixou confuso por um bom tempo porque não estava nem perto da declaração da matriz.
Talvez alguém possa se beneficiar das minhas duas horas de puxar o cabelo.
fonte
Esqueceu de tirar um ponteiro não alocado de
dealloc
. Eu estava obtendo o exc_bad_access no meu rootView de um UINavigationController, mas apenas algumas vezes. Presumi que o problema estava no rootView porque estava travando na metade do seu viewDidAppear {}. Acabou acontecendo apenas depois que eu exibi a visualização com o lançamento ruim do {}, e foi isso!"EXC_BAD_ACCESS" [Mudando para o processo 330] Nenhuma memória disponível para programar agora: inseguro para chamar malloc
Eu pensei que era um problema onde eu estava tentando alocar ... não onde eu estava tentando liberar um não alocado, D'oh!
fonte
Como lido com EXC_BAD_ACCESS
Às vezes, sinto que, quando um erro EXC_BAD_ACCESS é lançado, o xcode mostrará o erro na classe main.m, não fornecendo informações adicionais sobre o local da falha (às vezes).
Nesses momentos, podemos definir um ponto de interrupção excepcional no Xcode para que, quando a exceção for detectada, um ponto de interrupção seja colocado e intimamente diretamente ao usuário que a falha ocorreu nessa linha
fonte
Chamadas NSAssert () para validar parâmetros de método é bastante útil para rastrear e evitar passar nils também.
fonte
Eu apenas tive esse problema. Para mim, o motivo foi excluir um objeto gerenciado CoreData e tentar lê-lo posteriormente de outro local.
fonte
Venho depurando e refatorando o código para solucionar esse erro nas últimas quatro horas. Uma postagem acima me levou a ver o problema:
Propriedade antes:
Propriedade após:
Adeus
EXC_BAD_ACCESS
Muito obrigado pela sua resposta. Eu tenho lutado com esse problema o dia todo. Você é incrível!
fonte
Apenas para adicionar
O Lynda.com tem um DVD fantástico chamado
e o Capítulo 6, Lição 3, trata de EXEC_BAD_ACCESS e de trabalhar com Zombies.
Foi ótimo para mim entender, não apenas o código de erro, mas como posso usar o Zombies para obter mais informações sobre o objeto liberado.
fonte
Para verificar qual pode ser o erro
Use NSZombieEnabled.
Para ativar o recurso NSZombieEnabled no seu aplicativo:
Escolha Projeto> Editar executável ativo para abrir a janela Informações executáveis. Clique em argumentos. Clique no botão Adicionar (+) na seção "Variáveis a serem definidas no ambiente". Digite NSZombieEnabled na coluna Nome e YES na coluna Valor. Verifique se a marca de seleção da entrada NSZombieEnabled está selecionada.
Encontrei esta resposta no iPhoneSDK
fonte
Sei que isso foi perguntado há algum tempo, mas depois de ler este tópico, encontrei a solução para o XCode 4.2: Produto -> Editar esquema -> Guia Diagnóstico -> Ativar objetos zumbis
Ajudou-me a encontrar uma mensagem sendo enviada para um objeto desalocado.
fonte
Quando você tem uma recursão infinita, acho que você também pode ter esse erro. Este foi um caso para mim.
fonte
Ainda outra possibilidade: usando blocos em filas, pode facilmente acontecer que você tente acessar um objeto em outra fila, que já foi desalocada no momento. Normalmente, quando você tenta enviar algo para a GUI. Se o ponto de interrupção da exceção estiver sendo definido em um local estranho, talvez seja essa a causa.
fonte
Eu entendi porque eu não estava usando
[self performSegueWithIdentifier:sender:]
e-(void) prepareForSegue:(UIstoryboardSegue *)
certofonte
Não esqueça o
@
símbolo ao criar strings, tratandoC-strings
comoNSStrings
causaráEXC_BAD_ACCESS
.Usa isto:
Em vez disso:
PS - normalmente ao preencher o conteúdo de um
array
com muitos registros.fonte
O XCode 4 e superior foi simplificado com a Instruments. Basta executar Zombies em Instruments. Este tutorial explica bem: depuração exc_bad_access error xcode instruments
fonte