Ok, aqui está o negócio, eu odeio fazer perguntas sobre minha depuração e travamentos. Porque normalmente eu mesmo cuido delas, mas simplesmente não consigo resolver isso, mesmo depois de já ter visto várias perguntas .
Ok, então aqui está o problema, acho meu aplicativo ligado e desligado aleatoriamente travando com este rastreamento de pilha:
*** -[ViewController respondsToSelector:]: message sent to deallocated instance 0x1e5d2ef0
Onde ViewController
pode variar, às vezes o lugar onde meu código falha, NÃO tem relevância para aquele particular ViewController
e não possui ou chama isso.
Além disso, para obter o rastreamento do console, habilitei o Zombies, caso contrário, não obteria nenhuma impressão do console, apenas obteria:, o objc_msgSend
que eu sei que significa que estou enviando uma mensagem de algo que foi lançado. Mas não consigo descobrir onde é ... estou mesmo preso! Normalmente eu sempre depuro minhas falhas, então estou realmente preso nisso.
Novamente, isso trava em lugares diferentes em momentos diferentes, ligado e desligado. E o local em que ele cai quase não tem relevância para o ViewController
. E acho isso muito confuso.
Você precisa de algum do meu código? Eu tenho muitos arquivos e como ele está travando em lugares diferentes, distribuir meu código será uma bagunça!
Tentei adicionar breakpoints simbólicos sem sorte, e Zombies não está disponível no aplicativo Instruments para iOS. Não consigo executar meu aplicativo no simulador, pois ele possui estruturas de arquitetura incompatíveis.
Obrigado a todos ...
fonte
Respostas:
Use instrumentos para rastrear erros de instância desalocada. Crie o perfil de seu aplicativo ( Cmd ⌘+ I) e escolha o modelo Zumbis . Depois que seu aplicativo estiver em execução, tente travá-lo. Você deve conseguir algo assim:
Clique na seta ao lado do endereço no popover para mostrar o objeto que foi chamado depois de ser desalocado.
Você deve ver agora cada chamada que mudou, reter a contagem deste objeto. Isso pode ocorrer porque o envio de mensagens reter / liberar diretamente, bem como drenar pools de liberação automática ou inserir em NSArrays.
A coluna RefCt mostra reterCount depois que a ação foi chamada e o responsável pela chamada responsável mostra o nome da classe e o método em que foi executada. Quando você clica duas vezes em qualquer retenção / liberação, os instrumentos mostram a linha de código onde isso foi executado (se isso não estiver funcionando, você pode examinar a chamada selecionando-a e escolhendo sua contraparte no painel Detalhes estendidos ):
Isso permitirá que você examine todo o ciclo de vida do objeto retentCount e provavelmente você encontrará seu problema imediatamente. Tudo o que você precisa fazer é encontrar a retenção ausente para a versão mais recente .
fonte
release
, especificamente. O problema é qualquer desequilíbriorelease
. Também posso ser simplesmente um fracasso emretain
algo que você está observando e referenciando mais tarde.teve um problema semelhante. No meu caso, um viewController precisava obter eventos de navigationController, então ele estava se registrando como delegado do controlador de navegação:
O travamento ocorre quando aquele controlador foi desalocado, mas ainda era o delegado para o controlador de visualização. Adicionar este código no dealloc não teve efeito:
porque no ponto em que o dealloc é chamado, o controlador de exibição já foi removido da hierarquia de exibição, então self.navigationController é nulo, portanto a comparação falhará! :-(
A solução foi adicionar esse código para detectar o VC deixando a hierarquia de visualizações antes de realmente fazê-lo. Ele usa um método introduzido no iOS 5 para determinar quando a visualização está sendo exibida e não empurrada
Não há mais travamentos!
fonte
Para quem não consegue resolver, aqui estão algumas outras técnicas:
https://stackoverflow.com/a/12264647/539149
https://stackoverflow.com/a/5698635/539149
https://stackoverflow.com/a/9359792/539149
https://stackoverflow.com/a/15270549/539149
https://stackoverflow.com/a/12098735/539149
Você pode executar Instrumentos no Xcode 5 clicando no pop-up do projeto-> Editar Esquema ... Perfil -> Instrumento e escolher Alocações ou Vazamentos, então criar o perfil de seu aplicativo, então parar Instrumentos, clicar no botão de informação em Alocações e "Ativar Detecção NSZombie" .
No entanto, para as mensagens que vêm diretamente do com.apple.main-thread, isso provavelmente não revelará nada.
Bati minha cabeça nisso por mais de duas horas e a resposta acabou sendo um lançamento excessivo, que descobri comentando uma cópia do meu projeto por força bruta até encontrar o culpado:
O problema é que o release não define a variável como NULL.
Isso significa que defini-lo como NULL chama o release novamente, diminuindo o refcount e liberando a memória imediatamente até mais tarde, quando as variáveis que referenciam o viewController terminarem com ele.
Portanto, habilite o ARC ou certifique-se de que seu projeto use consistentemente release ou NULL, mas não ambos. Minha preferência é usar NULL porque então não há chance de fazer referência a um zumbi, mas torna mais difícil encontrar onde os objetos são liberados.
fonte
Eu tinha encontrado o mesmo problema no iOS ontem. Eu fiz IAP na subvisão "Sobre" do aplicativo e adicionei o Transaction Observer no viewDidLoad "Sobre". Quando comprei pela primeira vez, sem problemas, mas depois que voltei à janela principal e entrei sobre a subvisualização para comprar novamente, o problema "mensagem enviada para instância desalocada" aconteceu e o aplicativo travou.
Depois de remover o Transaction Observer no dealloc, o problema está resolvido.
fonte
zombie
objeto para compras no aplicativo. Depois de muitas horas de escavação, encontrei este ... UM GRANDE OBRIGADO Cara.Eu tive um problema muito semelhante e descobri que era devido ao conjunto de delegados do controlador de navegação.
O que segue resolveu meu problema,
fonte
Tive o mesmo problema no OS X.
Para resolver este
- (void)dealloc
método não basta como o @SoftwareEvolved já disse. Mas infelizmente- (void)viewWillDisappear
está disponível apenas na versão 10.10 e posterior.Eu introduzi o método personalizado em minha subclasse NSViewController, onde definir todas as referências perigosas para zumbis como nulo. No meu caso, eram
NSTableView
propriedades (delegate
edataSource
).Isso é tudo. Cada vez que estou prestes a remover a visualização da visualização, preciso chamar este método.
fonte
Eu tive o mesmo problema. Foi difícil descobrir qual delegado causou problema, porque ele não indica nenhuma linha ou instrução de código. Então, tentei de alguma forma. Talvez seja útil para você.
fonte