Pergunta

Eu sou novo para o desenvolvimento do iPhone e XCode em geral e não têm idéia de como começar a solucionar um sinal EXC_BAD_ACCESS. Como posso obter XCode para quebrar na linha exata que está causando o erro?


Eu não consigo obter XCode a paragem na linha causando o problema, mas eu vejo as seguintes linhas no meu console de depuração:

Sun 25 de outubro 15:12:14 jasonsmacbook TestProject [1289]: CGContextSetStrokeColorWithColor: contexto inválido

Sun 25 de outubro 15:12:14 jasonsmacbook TestProject [1289]: CGContextSetLineWidth: contexto inválido

Sun 25 de outubro 15:12:14 jasonsmacbook TestProject [1289]: CGContextAddPath: contexto inválido

Sun 25 de outubro 15:12:14 jasonsmacbook TestProject [1289]: CGContextDrawPath: contexto inválido

2009-10-25 15: 12: 14,680 LanderTest [1289: 207] *** - [CFArray objectAtIndex:]: mensagem enviada para instância desalocada 0x3c4e610

Agora, eu estou tentando desenhar o contexto eu recuperar a partir UIGraphicsGetCurrentContext() e passar para o objeto que eu quero desenhar com.


Além disso julgamento e depuração de erros e eu achei que um NSMutableArray Eu tenho uma propriedade para a minha classe era um zumbi. Fui para a função init para a classe e aqui está o código que eu estava usando:

if ((self = [super init])) {
        NSMutableArray *array = [NSMutableArray array];
        self.terrainBlocks = array;
        [array release];
    }
    return self;    
}

Eu removi a linha [array release] e já não me dá o sinal EXC_BAD_ACCESS, mas agora estou confuso sobre por que isso funciona. Eu pensei que quando eu usei a propriedade, manteve-lo automaticamente para mim, e, portanto, eu deveria liberá-lo de dentro init para que eu não tenho um vazamento. Estou completamente confuso sobre como isso funciona e todos os guias e perguntas StackOverflow eu só li me confundir mais sobre como definir propriedades dentro do meu método init. Não parece haver consenso sobre qual caminho é o melhor.

Foi útil?

Solução

Para quaisquer erros EXC_BAD_ACCESS, que normalmente são tentando enviar uma mensagem para um objeto lançado. O BEST forma de acompanhar estes para baixo é o uso NSZombieEnabled .

Isso funciona, nunca realmente liberar um objeto, mas por envolvê-lo como um "zumbi" e definindo um sinalizador dentro dela que diz que normalmente teria sido liberada. Dessa forma, se você tentar acessá-lo novamente, ele ainda sabia o que era antes de você cometeu o erro, e com este pouco de informação, normalmente você pode recuar para ver qual era o problema.

Ela ajuda especialmente em threads em segundo plano quando o depurador às vezes craps para fora em alguma informação útil.

muito importante notar no entanto, é que você precisa de 100% certeza de que essa é apenas em seu código de depuração e não o seu código de distribuição. Porque nada é lançado, o aplicativo irá vazar e vazar e vazar. Para me lembrar de fazer isso, eu coloquei esse log no meu AppDelegate:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

Se você precisar de ajuda para encontrar a linha exata, fazer uma compilação-and-depuração ( CMD-Y ) em vez de um Build-and-Run ( CMD-R ). Quando as falhas de aplicativos, o depurador irá mostrar-lhe exatamente qual linha e em combinação com NSZombieEnabled, você deve ser capaz de descobrir exatamente o porquê.

Outras dicas

Sobre a sua matriz. A linha

NSMutableArray *array = [NSMutableArray array];

não realmente dar-lhe um objeto mantido, mas sim um objeto de disparo automático. Provavelmente fica retida na linha seguinte, mas então você não deve liberá-lo na terceira linha. Consulte este

Esta é a regra fundamental:

Você se apropriar de um objeto se você criá-lo usando um método cujo nome começa com “alloc” ou “novo” ou contém “cópia” (por exemplo, alloc, newObject, ou mutableCopy), ou se você enviá-lo a reter mensagem. Você é responsável por abandonar a propriedade de objetos que você possui usando liberação ou disparo automático. Qualquer outra vez que você receber um objeto, você não deve liberá-lo.

No Xcode 4, você pode ativar Zombies clicando no menu suspenso Esquema (em cima à esquerda, ao lado do botão de parada) -> Editar Esquema -> Diagnóstico Tab -> Ativar Zombie Objetos

Xcode / gdb sempre quebras no EXC_BAD_ACCESS, você só precisa trabalhar o seu caminho até a pilha de chamadas para encontrar o código que desencadeou.

Note que esses tipos de erros ocorrem frequentemente com objetos autoreleased, o que significa que a causa final do problema não será na pilha de chamadas que EXC_BAD_ACCESS acionado. Foi quando NSZombieEnabled e NSAutoreleaseFreedObjectCheckEnabled se tornar útil.

Uma nova resposta para uma discussão antiga ... no Xcode 4 a maneira mais eficaz de diagnosticar exceções EXC_BAD_ACCESS é usar Instruments ao perfil seu aplicativo (de XCode clique Product / perfil e escolha Zombies). Isso ajudará você a identificar mensagens enviadas para objetos deallocated.

A partir das aulas de Stanford CS193P: se você adicionar um ponto de interrupção (manualmente, editando pontos de interrupção) para a symbolobjc_exception_throw você pode obter uma melhor imagem muito mais do que deu errado - deixar as coisas avançar para o ponto onde as paradas depurador por si só tende a obscurecer as coisas e estragar o rastreamento de pilha. Quando você parar em objc_exception_throw muitas vezes você pode olhar para trás para exatamente o acesso / operação causou o problema.

Outra abordagem útil é definir pontos de interrupção que irá acionar diretamente após a exceção ocorre:

Abra a janela breakpoints (Run - Show - Pontos de Interrupção) e adicionar dois pontos de interrupção simbólico chamado “objc_exception_throw” e “[raise NSException]"

De: http://blog.emmerinc.be/index.php/2009/03/19/break-on-exception-in-xcode/

Só queria acrescentar para os outros que estão vindo de uma web, em busca de soluções para o mesmo erro, mas com diferentes erro. No meu caso eu tenho o mesmo erro quando tentei instanciar NSDictionary com erro de digitação no nome da chave onde eu esqueci de acrescentar "@" na frente de minha chave:

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys: myObj1, @"goodKey", myObj2, "badkey @ is missing in front", nil];

Eu espero que eu não perca uma resposta idêntica, mas eu descobri que é possível para alguns projetos para lançar este erro devido à execução em simuladores para iOS versões mais antigas que podem ser incompatíveis com uma dependência ou estrutura do projeto. Eu estava perseguindo um deles para baixo por muito tempo antes de perceber que apenas estava acontecendo nas versões simulador -older-, como o iPhone 4S, o aplicativo não foi sequer deveria tentar apoio.

teria sido bom ter obtido uma mais detalhado mensagem de erro, mas eu imagino que é da responsabilidade do quadro onde se originou ... De qualquer forma, este é um pouso de pesquisa bastante comum e talvez isso ajude alguém Goofing -se tão mal quanto eu me encontrei.

Antes de zumbis permitindo Eu recomendo primeiro se livrar de todos os avisos (se tiver algum). Coisas simples como uma função não nula sem causa returncan este erro. Se você não tem avisos proceder como as outras respostas sugerem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top