ARC es solo jugar retención / liberación antigua (MRC) con el compilador averiguando cuándo llamar a retención / liberación. Tiende a tener un mayor rendimiento, menor uso de memoria pico y un rendimiento más predecible que un sistema GC.
Por otro lado, algunos tipos de estructura de datos no son posibles con ARC (o MRC), mientras que GC puede manejarlos.
Como ejemplo, si tiene una clase llamada nodo, y el nodo tiene una matriz NSA de elementos secundarios, y una única referencia a su elemento primario que "simplemente funciona" con GC. Con ARC (y el conteo manual de referencias también) tiene un problema. Se hará referencia a cualquier nodo dado desde sus elementos secundarios y también desde su elemento primario.
Me gusta:
A -> [B1, B2, B3]
B1 -> A, B2 -> A, B3 -> A
Todo está bien mientras usa A (digamos a través de una variable local).
Cuando haya terminado con él (y B1 / B2 / B3), un sistema GC finalmente decidirá mirar todo lo que pueda encontrar a partir de los registros de pila y CPU. Nunca encontrará A, B1, B2, B3, por lo que los finalizará y reciclará la memoria en otros objetos.
Cuando usa ARC o MRC, y termina con A, tiene un recuento de 3 (B1, B2 y B3 todos lo referencian), y B1 / B2 / B3 tendrán un recuento de referencia de 1 (NSArray de A tiene una referencia a cada). Por lo tanto, todos esos objetos permanecen vivos aunque nada pueda usarlos.
La solución común es decidir que una de esas referencias debe ser débil (no contribuir al recuento de referencias). Eso funcionará para algunos patrones de uso, por ejemplo, si hace referencia a B1 / B2 / B3 solo a través de A. Sin embargo, en otros patrones falla. Por ejemplo, si a veces se aferrará a B1 y espera volver a subir a través del puntero principal y encontrar A. Con una referencia débil si solo se aferra a B1, A puede (y normalmente) se evaporará y tomará B2 y B3 con eso.
A veces esto no es un problema, pero algunas formas muy útiles y naturales de trabajar con estructuras complejas de datos son muy difíciles de usar con ARC / MRC.
Entonces, ARC apunta al mismo tipo de problemas que los objetivos de GC. Sin embargo, ARC funciona en un conjunto de patrones de uso más limitado que GC, por lo que si toma un lenguaje GC (como Java) e injerta algo como ARC en él, algunos programas ya no funcionarían (o al menos generarían toneladas de memoria abandonada , y puede causar serios problemas de intercambio o quedarse sin memoria o espacio de intercambio).
También puede decir que ARC le da mayor prioridad al rendimiento (o tal vez a la previsibilidad) mientras que GC le da mayor prioridad a ser una solución genérica. Como resultado, GC tiene demandas de CPU / memoria menos predecibles y un rendimiento más bajo (normalmente) que ARC, pero puede manejar cualquier patrón de uso. ARC funcionará mucho mejor para muchos patrones de uso comunes, pero para unos pocos (¡válidos!) Patrones de uso se caerá y morirá.