Ainda não usei o ARC, já que a maioria do código do projeto em que estou trabalhando no momento foi escrito antes do iOS 5.0.
Eu estava me perguntando: a conveniência de não reter / liberar manualmente (e, presumivelmente, um código mais confiável que vem como resultado?) Supera qualquer 'custo' de usar o ARC? Quais são suas experiências com o ARC e você o recomendaria?
Assim:
- Qual é o benefício que o ARC pode trazer para um projeto?
- O ARC tem um custo como a coleta de lixo em Java?
- Você tem usado o ARC e, em caso afirmativo, como o encontrou até agora?
iphone
objective-c
ipad
ios5
automatic-ref-counting
Simon Withington
fonte
fonte
Respostas:
Não há nenhuma desvantagem. Use-o. Faça hoje. É mais rápido que seu código antigo. É mais seguro do que seu código antigo. É mais fácil do que seu código antigo. Não é coleta de lixo. Não tem sobrecarga de tempo de execução do GC. O compilador insere retém e libera em todos os lugares que você deveria ter de qualquer maneira. Mas é mais inteligente do que você e pode otimizar aqueles que não são realmente necessários (assim como pode desfazer loops, eliminar variáveis temporárias, funções embutidas, etc.)
OK, agora vou falar sobre as pequenas desvantagens:
Se você é um desenvolvedor de ObjC de longa data, ficará nervoso por cerca de uma semana ao ver o código ARC. Você vai superar isso muito rapidamente.
Existem algumas complicações (muito) pequenas na ponte para o código do Core Foundation. Existem um pouco mais de complicações em lidar com qualquer coisa que trate um
id
como umvoid*
. Coisas como C-arrays deid
podem levar um pouco mais de reflexão para serem feitas corretamente. Manipulação extravagante de ObjCva_args
também pode causar problemas. A maioria das coisas que envolvem matemática em um ponteiro ObjC é mais complicada. Você não deve ter muito disso em qualquer caso.Você não pode colocar um
id
em astruct
. Isso é bastante raro, mas às vezes é usado para empacotar dados.Se você não seguiu a nomenclatura KVC correta e misturou código ARC e não ARC, terá problemas de memória. ARC usa nomenclatura KVC para tomar decisões sobre o gerenciamento de memória. Se for todo código ARC, então não importa porque fará o mesmo "errado" em ambos os lados. Mas se for misto ARC / não ARC, então há uma incompatibilidade.
ARC vazará memória durante lançamentos de exceção ObjC. Uma exceção ObjC deve estar muito próxima ao encerramento do seu programa. Se você está detectando um número significativo de exceções ObjC, está usando-as incorretamente. Isso pode ser corrigido usando
-fobjc-arc-exceptions
, mas incorre nas penalidades discutidas abaixo:O ARC não vazará memória durante o lançamento de exceções ObjC ou C ++ no código ObjC ++, mas isso prejudica o desempenho de tempo e espaço. Esta é mais uma em uma longa lista de razões para minimizar o uso de ObjC ++.
ARC não funcionará em iPhoneOS 3 ou Mac OS X 10.5 ou anterior. (Isso me impede de usar o ARC em muitos projetos.)
__weak
os ponteiros não funcionam corretamente no iOS 4 ou Mac OS X 10.6, o que é uma pena, mas bastante fácil de contornar.__weak
as dicas são ótimas, mas não são o ponto de venda nº 1 da ARC.Para mais de 95% do código, o ARC é brilhante e não há razão para evitá-lo (desde que você possa lidar com as restrições de versão do sistema operacional). Para código não ARC, você pode passar
-fno-objc-arc
arquivo por arquivo. Infelizmente, o Xcode torna isso muito mais difícil do que deveria ser na prática. Você provavelmente deve mover o código não ARC para um xcodeproj separado para simplificar isso.Em conclusão, mude para o ARC assim que puder e nunca olhe para trás.
EDITAR
Já vi alguns comentários do tipo "usar o ARC não substitui o conhecimento das regras de gerenciamento de memória Cocoa". Isso é verdade, mas é importante entender por que e por que não. Primeiro, se todo o seu código usar ARC e você violar as Três Palavras Mágicasem todo o lugar, você ainda não terá problemas. Chocante dizer, mas aí está. O ARC pode reter algumas coisas que você não pretendia reter, mas também as liberará, portanto, isso nunca terá importância. Se eu fosse dar uma nova aula em Cocoa hoje, provavelmente não gastaria mais do que cinco minutos nas regras reais de gerenciamento de memória e provavelmente apenas mencionaria as regras de nomenclatura de gerenciamento de memória ao discutir a nomenclatura KVC. Com o ARC, acredito que você poderia realmente se tornar um programador iniciante decente sem aprender as regras de gerenciamento de memória.
Mas você não poderia se tornar um programador intermediário decente. Você precisa conhecer as regras para fazer a ponte corretamente com o Core Foundation, e todo programador intermediário precisa lidar com o CF em algum ponto. E você precisa conhecer as regras para código ARC / MRC misto. E você precisa conhecer as regras quando começar a mexer com
void*
ponteiros paraid
(que você continua a precisar para executar KVO corretamente). E blocos ... bem, o gerenciamento de memória em bloco é simplesmente estranho.Portanto, meu ponto é que o gerenciamento de memória subjacente ainda é importante, mas onde eu costumava gastar um tempo significativo declarando e reafirmando as regras para novos programadores, com o ARC ele está se tornando um tópico mais avançado. Prefiro fazer com que os novos desenvolvedores pensem em termos de gráficos de objetos em vez de preencher suas cabeças com as chamadas subjacentes para
objc_retain()
.fonte
Melhor, respostas mais técnicas do que as minhas virão, mas aqui vai:
fonte
O benefício é um grau significativo de proteção contra erros comuns de gerenciamento de memória. Vazamentos causados por falha na liberação de um objeto e travamentos devido à falha em reter ou liberação prematura de um objeto devem ser significativamente reduzidos. Você ainda precisa entender o modelo de memória contada por referência para que possa classificar suas referências como fortes ou fracas, evitar ciclos de retenção e assim por diante.
Não há coleta de lixo no iOS. ARC é semelhante ao GC no sentido de que você não precisa reter ou liberar objetos manualmente. É diferente do GC porque não há coletor de lixo. O modelo de retenção / liberação ainda se aplica, é só que o compilador insere as chamadas de gerenciamento de memória apropriadas em seu código para você no momento da compilação.
É um pouco desconcertante se você está acostumado com a contagem de referências, mas é só uma questão de se acostumar e aprender a confiar que o compilador realmente fará a coisa certa. Parece uma continuação da mudança nas propriedades que veio com Objective-C 2.0, que foi outro grande passo em direção à simplificação do gerenciamento de memória. Sem as chamadas manuais de gerenciamento de memória, seu código se torna um pouco mais curto e fácil de ler.
O único problema com o ARC é que ele não é compatível com versões mais antigas do iOS, então você precisa levar isso em consideração antes de decidir adotá-lo.
fonte
Acho que o ARC é uma ótima ideia. Comparado ao GC, você pode ter seu bolo e comê-lo. Eu tendo a acreditar que o MRC impõe uma 'disciplina' inestimável para o gerenciamento de memória que todos se beneficiariam em ter. Mas também concordo que a verdadeira questão a ter em conta é a propriedade do objeto e os gráficos de objeto (como muitos apontaram), e não as contagens de referência de baixo nível per se.
Para concluir: ARC NÃO é um passe livre para deixar de lado a memória; é uma ferramenta para ajudar o homem a evitar tarefas repetitivas, que causam estresse e estão sujeitas a erros, portanto, melhor delegadas a uma máquina (o compilador, neste caso).
Dito isso, pessoalmente sou um artesão e ainda não fiz a transição. Acabei de começar a usar o Git ...
ATUALIZAÇÃO: Portanto, migrei todo o meu jogo, incluindo a biblioteca gl, e sem problemas até agora (exceto com o assistente de migração no Xcode 4.2). Se você está começando um novo projeto, vá em frente.
fonte
Eu o usei em alguns projetos (reconhecidamente pequenos) e só tenho boas experiências, tanto em desempenho quanto em confiabilidade.
Uma pequena nota de cautela é que você precisa aprender a fazer: se não: s de referências fracas para não causar nenhum loop de referência se você estiver codificando sua IU sozinho, o designer tende a fazer um bom trabalho automaticamente se você configurar sua GUI usando-o.
fonte
A única desvantagem que encontrei é se você usa uma biblioteca com muitas funções e dados CoreFoundation. No MRC, você não precisa se preocupar em usar um em
CFStringRef
vez de umNSString*
. No ARC, você deve especificar como os dois interagem (ponte básica? Liberar o objeto CoreFoundation e movê-lo para ARC? Fazer um objeto Cocoa como um objeto retido CoreFoundation +1?) Além disso, no OS X, está disponível apenas no 64- código de bits (embora eu tenha um cabeçalho que contorna isso ...).fonte