O principal problema relacionado à memória que você ainda precisa conhecer é o de manter ciclos. Isso ocorre quando um objeto tem um ponteiro forte para outro, mas o objeto de destino tem um ponteiro forte de volta ao original. Mesmo quando todas as outras referências a esses objetos são removidas, elas ainda se mantêm firmes e não serão liberadas. Isso também pode acontecer indiretamente, por uma cadeia de objetos que pode ter o último na cadeia se referindo a um objeto anterior.
É por esta razão que o __unsafe_unretained
e __weak
qualificadores de propriedade existe. O primeiro não retém nenhum objeto para o qual aponta, mas deixa em aberto a possibilidade desse objeto desaparecer e apontar para uma memória ruim, enquanto o último não retém o objeto e se define automaticamente como zero quando seu destino é desalocado. Dos dois, __weak
geralmente é preferido nas plataformas que o suportam.
Você usaria esses qualificadores para coisas como delegados, nos quais não deseja que o objeto retenha seu delegado e potencialmente leve a um ciclo.
Outro par de preocupações significativas relacionadas à memória são o manuseio de objetos e a memória do Core Foundation alocados usando malloc()
para tipos como char*
. O ARC não gerencia esses tipos, apenas objetos Objective-C, portanto você ainda precisará lidar com eles. Os tipos de Core Foundation podem ser particularmente difíceis, porque às vezes precisam ser conectados a objetos Objective-C correspondentes e vice-versa. Isso significa que o controle precisa ser transferido para a frente e para trás do ARC ao fazer a ponte entre os tipos de CF e o Objective-C. Algumas palavras-chave relacionadas a essa ponte foram adicionadas, e Mike Ash tem uma ótima descrição de vários casos de ponte em sua extensa redação do ARC .
Além disso, existem vários outros casos menos frequentes, mas ainda potencialmente problemáticos, nos quais a especificação publicada entra em detalhes.
Grande parte do novo comportamento, baseado em manter objetos por perto, desde que haja um forte indicador para eles, é muito semelhante à coleta de lixo no Mac. No entanto, os fundamentos técnicos são muito diferentes. Em vez de ter um processo de coletor de lixo que é executado em intervalos regulares para limpar objetos que não são mais apontados, esse estilo de gerenciamento de memória depende das regras rígidas de retenção / liberação que todos nós precisamos obedecer no Objective-C.
O ARC simplesmente pega as tarefas repetitivas de gerenciamento de memória que tivemos que fazer há anos e as transfere para o compilador, para que nunca mais tenhamos que nos preocupar com elas. Dessa forma, você não tem os problemas de parada ou os perfis de memória do dente de serra experimentados nas plataformas de coleta de lixo. Eu experimentei isso em meus aplicativos Mac coletados pelo lixo e estou ansioso para ver como eles se comportam no ARC.
Para obter mais informações sobre coleta de lixo versus ARC, consulte esta resposta muito interessante de Chris Lattner na lista de correspondência do Objective-C , onde ele lista muitas vantagens do ARC sobre a coleta de lixo do Objective-C 2.0. Encontrei vários dos problemas de GC que ele descreve.
O ARC não o ajudará com memória não ObjC, por exemplo, se você
malloc()
precisar, ainda precisafree()
disso.O ARC pode ser enganado
performSelector:
se o compilador não conseguir descobrir qual é o seletor (o compilador gerará um aviso sobre isso).O ARC também gerará código seguindo as convenções de nomenclatura da ObjC; portanto, se você combinar o código ARC e o MRC, poderá obter resultados surpreendentes se o código MRC não fizer o que o compilador acha que os nomes prometem.
fonte
Ocorreu um vazamento de memória no meu aplicativo devido aos quatro problemas a seguir:
Felizmente, me deparei com a seguinte postagem no blog e consegui corrigi-las: http://www.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/
fonte
O ARC também não gerenciará os tipos de CoreFoundation. Você pode 'unir' eles (Usando
CFBridgingRelease()
), mas apenas se você for usá-lo como um objeto Objective-C / Cocoa. Observe que CFBridgingRelease apenas diminui a contagem de retenção da CoreFoundation em 1 e a move para o ARC da Objective-C.fonte
O Xcode 9 fornece uma ótima ferramenta para encontrar esse tipo de problemas. É chamado: " Debug Memory Graph ". Usando-o, você pode encontrar seu objeto vazado por tipo de classe e pode ver claramente quem possui uma forte referência a ele, liberando-o de lá e resolvendo o seu problema. Também detecta ciclos de memória.
Veja mais informações sobre como usá-lo
fonte