Alguém pode me dar uma mão sobre este stacktrace no iPhone app?
-
12-09-2019 - |
Pergunta
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x30011940 in objc_msgSend ()
#1 0x30235f24 in CFRelease ()
#2 0x308f497c in -[UIImage dealloc] ()
#3 0x30236b78 in -[NSObject release] ()
#4 0x30a002a0 in FlushNamedImage ()
#5 0x30250a26 in CFDictionaryApplyFunction ()
#6 0x30a001a4 in _UISharedImageFlushAll ()
#7 0x30a00738 in +[UIImage(UIImageInternal) _flushCacheOnMemoryWarning:] ()
#8 0x3054dc80 in _nsnote_callback ()
#9 0x3024ea58 in _CFXNotificationPostNotification ()
#10 0x3054b85a in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#11 0x3054dbc0 in -[NSNotificationCenter postNotificationName:object:] ()
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
#13 0x30a006a8 in -[UIApplication _receivedMemoryNotification] ()
#14 0x30a005d8 in _memoryStatusChanged ()
#15 0x30217416 in __CFNotificationCenterDarwinCallBack ()
#16 0x3020d0b0 in __CFMachPortPerform ()
#17 0x30254a76 in CFRunLoopRunSpecific ()
#18 0x3025416a in CFRunLoopRunInMode ()
#19 0x320452a4 in GSEventRunModal ()
#20 0x308f037c in -[UIApplication _run] ()
#21 0x308eea94 in UIApplicationMain ()
#22 0x00002096 in main (argc=1, argv=0x2ffff514)
Atualmente tenho um erro muito estranho no meu programa. Às vezes acontece, às vezes, isso não acontece. Mas aqui está um resumo do que está acontecendo:
Quando o programa inicia-se:
- dados guardados (a uma curta plist consiste em 13 elementos) é carregado, se ela existir.
- uma enorme plist contendo 1014 cordas é carregado na NSMutableDictionary.
- plist outra contendo 78 cordas é carregado para um NSArray.
- um filme .mp4 é jogado.
O erro ocorre a uma parte onde OpenGL ES Ver está a ser removida e o utilizador está a ponto de vista de uma das cordas das cordas de 1014 na NSMutableDictionary.
Este erro nunca ocorrem no simulador. Ele ocorre apenas no iPhone, e às vezes ele funciona muito bem, mas às vezes esmaga.
No entanto, depois de ler o stacktrace, vejo CFDictionaryApplyFunction lá, então eu pensei que poderia ser uma das possíveis causas. Será que é porque no simulador, ele lê as coisas tão rápido que todo o dicionário do plist é carregado em um instante, enquanto no dispositivo, ele lê mais lento? Honestamente, eu não sei exatamente como funciona o dicionário. Será que ler todas 1014 cordas em um instante, ou ele usa alguns outros tópicos para ler devagar? Conselho por favor. Obrigado.
Solução
Quando você receber um EXC_BAD_ACCESS
, que muitas vezes significa que você está tentando chamar um método em um objeto que não está lá -. Provavelmente porque tem sido desalocada
Sobre a meio caminho do traço, há alguns alerta de memória chamadas, tais como:
#12 0x30a00710 in -[UIApplication _performMemoryWarning] ()
O que faz com que pareça que nenhum de seu código é diretamente , causando o acidente, mas sim uma forma de notificação quando a memória fica fraca.
Closer to enquadrar # 0, parece estar tentando limpar o cache de um objeto UIImage
, e este parece ser o mau acesso.
Com base nisso, um palpite é que você está atribuindo um ponteiro para o valor de retorno autoreleased de um construtor de conveniência; em seguida, o objeto é autoreleased, e você pode pensar que é bom porque você não usar a imagem diretamente, mas a memória de aviso tenta acessá-lo. Por exemplo:
@interface MyClass {
UIImage* myImage;
}
// ...
- (id) init { /* the usual stuff */
myImage = [UIImage imageNamed:@"bob_the.png"];
return self;
}
Neste exemplo, mesmo se você tem uma propriedade reter configurado em myImage
, você não está realmente mantendo a imagem a menos que você defina o valor via self.myImage
. Então, logo após esta chamada, a imagem é liberado, e você tem um ponteiro para terra de ninguém.
Sem ver o código, não tenho nenhuma maneira de saber se isso é o que está realmente acontecendo, mas é um tipo de erro que é fácil de fazer.
Estas questões relacionadas dar dicas sobre acidentes semelhantes: EXC_BAD_ACCESS
depuração questão 1 questão 2 .
Finalmente, se nada disso ajuda, sugiro encontrar um reprodução mínima do seu problema. A maneira mais difícil de fazer isso é copiar seu código, corte a metade, para ver se o erro ainda está lá, e repita até obter o menor código que você pode encontrar que reproduz o erro. É geralmente muito mais fácil de depurar de lá (e mais postable como uma pergunta stackoverflow, também!) Se você sabe o caminho mais fácil, deixe-me saber.
Outras dicas
Você pode querer definir a variável de ambiente NSZombiesEnabled
. Desta forma, a sua aplicação não vai falhar com EXC_BAD_ACCESS
ao acessar objetos lançados, mas registra uma mensagem informativa para o seu console. Este post explica muito bem o que acontece e como configurá-lo no XCode. De qualquer forma, NUNCA se esqueça de desabilitar essa opção nas versões de produção, pois caso contrário os seus objectos nunca será lançado!