A ARC o no a ARC? ¿Cuáles son los pros y los contras?

Aún no he usado ARC, ya que la mayoría del código del proyecto en el que estoy trabajando en este momento fue escrito antes de iOS 5.0.

Me preguntaba si la conveniencia de no retener / liberar manualmente (¿y probablemente un código más confiable como resultado?) Supera cualquier “costo” de usar ARC? ¿Cuáles son sus experiencias con ARC y lo recomendaría?

Asi que:

  • ¿Cuánto beneficio puede aportar ARC a un proyecto?
  • ¿ARC tiene un costo como la recolección de basura en Java?
  • ¿Has estado usando ARC y, de ser así, cómo lo has encontrado hasta ahora?

No hay inconveniente. Úselo. Hazlo hoy. Es más rápido que tu código anterior. Es más seguro que tu código anterior. Es más fácil que tu código anterior. No es recolección de basura. No tiene overhead de tiempo de ejecución de GC. El comstackdor inserta retenciones y lanzamientos en todos los lugares que debería tener de todos modos. Pero es más inteligente que usted y puede optimizar los que realmente no son necesarios (al igual que puede desenrollar bucles, eliminar variables temporales, funciones en línea, etc.)

OK, ahora te hablaré sobre las pequeñas desventajas:

  • Si eres un desarrollador ObjC desde hace mucho tiempo, te moverás durante aproximadamente una semana cuando veas el código ARC. Lo superarás rápidamente.

  • Existen algunas (muy) pequeñas complicaciones en el código de Core Foundation. Hay un poco más de complicaciones al tratar con cualquier cosa que trate a una id como un void* . Cosas como C-arrays de id pueden tomar un poco más de pensar en hacer correctamente. El manejo elegante de ObjC va_args también puede causar problemas. La mayoría de las cosas que involucran matemáticas en un puntero ObjC son más complicadas. No deberías tener mucho de esto en ningún caso.

  • No puedes poner una id en una struct . Esto es bastante raro, pero a veces se usa para empacar datos.

  • Si no siguió los nombres correctos de KVC e intermezcla el código ARC y el código que no es ARC, tendrá problemas de memoria. ARC utiliza la denominación de KVC para tomar decisiones sobre la gestión de la memoria. Si es todo el código ARC, entonces no importa porque lo hará de la misma manera “incorrecta” en ambos lados. Pero si está mezclado ARC / no ARC, entonces hay un desajuste.

  • ARC perderá memoria durante los lanzamientos de excepción ObjC. Una excepción ObjC debe ser muy cercana a la finalización de su progtwig. Si está atrapando una cantidad significativa de excepciones ObjC, las está usando incorrectamente. Esto se puede -fobjc-arc-exceptions usando -fobjc-arc-exceptions , pero incurre en las penalizaciones que se describen a continuación:

  • ARC no perderá memoria durante la excepción ObjC o C ++ arroja el código ObjC ++, pero esto es a costa del rendimiento en tiempo y espacio. Este es otro más en una larga lista de razones para minimizar el uso de ObjC ++.

  • ARC no funcionará en absoluto en iPhoneOS 3 o Mac OS X 10.5 o anterior. (Esto me impide usar ARC en muchos proyectos).

  • __weak indicadores __weak no funcionan correctamente en iOS 4 o Mac OS X 10.6, lo cual es una pena, pero es bastante fácil de evitar. __weak indicadores __weak son geniales, pero no son el punto de venta # 1 de ARC.

Con un 95% de código, ARC es shiny y no hay ningún motivo para evitarlo (siempre que pueda manejar las restricciones de la versión del sistema operativo). Para código que no es ARC, puede pasar -fno-objc-arc archivo por archivo. Desafortunadamente, Xcode hace que esto sea mucho más difícil de lo que debería ser en la práctica. Probablemente deberías mover código que no sea ARC a un xcodeproj separado para simplificar esto.

En conclusión, cambie a ARC tan pronto como pueda y nunca mire hacia atrás.


EDITAR

He visto un par de comentarios como “usar ARC no es un sustituto para conocer las reglas de administración de la memoria Cocoa”. Esto es mayormente cierto, pero es importante entender por qué y por qué no. Primero, si todo tu código usa ARC, y violas las Tres Palabras Mágicas por todas partes, no tendrás problemas. Escandaloso decirlo, pero ahí lo tienes. ARC podría retener algunas cosas que no quisiste retener, pero las liberará también, por lo que nunca importará. Si estuviera enseñando una nueva clase en Cocoa hoy, probablemente no dedicaría más de cinco minutos a las reglas de administración de memoria, y probablemente solo mencionaría las reglas de nombres de administración de memoria mientras hablaba de nombres de KVC. Con ARC, creo que en realidad podría convertirse en un progtwigdor principiante decente sin aprender las reglas de administración de memoria en absoluto.

Pero no podrías convertirte en un progtwigdor intermedio decente. Necesita conocer las reglas para establecer un puente correcto con Core Foundation, y cada progtwigdor intermedio debe tratar con CF en algún momento. Y necesita conocer las reglas para el código mixto ARC / MRC. Y necesita conocer las reglas cuando comienza a jugar con void* punteros a la id (que sigue necesitando realizar KVO correctamente). Y bloques … bueno, bloquear la administración de memoria es simplemente extraño.

Así que mi punto es que la administración de la memoria subyacente sigue siendo importante, pero cuando solía dedicar un tiempo significativo a establecer y replantear las reglas para los nuevos progtwigdores, con ARC se está convirtiendo en un tema más avanzado. Prefiero que los nuevos desarrolladores piensen en términos de gráficos de objetos en lugar de llenar sus cabezas con las llamadas subyacentes a objc_retain() .

Serán mejores respuestas técnicas que las mías, pero aquí va:

  • ARC! = Recolección de basura. No hay penalización de tiempo de ejecución, se realiza en tiempo de comstackción.
  • ¡ARC también! = Simplemente libera automáticamente todo, como sugieres en tu comentario. Lea los documentos
  • Es impresionante una vez que te das cuenta de cuánta gestión de referencia manual estás haciendo
  • Úselo!
  • Un inconveniente: mantener el código antiguo, que no es de arco, de repente se vuelve muy tedioso.

¿Cuánto beneficio puede aportar ARC a un proyecto?

El beneficio es un grado significativo de protección contra errores comunes de administración de memoria. Las fugas causadas por la falla en la liberación de un objeto y los lockings debido a la falla en retener o liberar prematuramente un objeto deberían reducirse significativamente. Aún necesita comprender el modelo de memoria contada de referencia para que pueda clasificar sus referencias como fuertes o débiles, evitar retener ciclos, y así sucesivamente.

¿Cuánto cuesta realmente la recolección de basura?

No hay recolección de basura en iOS. ARC es similar a GC en que no tiene que retener o liberar objetos manualmente. A diferencia de GC, no existe un recolector de basura. El modelo de retención / liberación todavía se aplica, es solo que el comstackdor inserta las llamadas de administración de memoria apropiadas en su código en tiempo de comstackción.

¿Has estado usando ARC y, de ser así, cómo lo has encontrado hasta ahora?

Es un poco desconcertante si está acostumbrado a hacer referencia al recuento, pero eso es solo cuestión de acostumbrarse y aprender a confiar en que el comstackdor realmente hará lo correcto. Se siente como una continuación del cambio en las propiedades que vino con Objective-C 2.0, que fue otro gran paso hacia la simplificación de la administración de la memoria. Sin las llamadas de administración de memoria manual, su código se vuelve un poco más corto y más fácil de leer.

El único problema con ARC es que no es compatible con las versiones anteriores de iOS, por lo que debe tenerlo en cuenta antes de decidirse a adoptarlo.

Creo que ARC es una gran idea. Comparado con GC, puedes tener tu pastel y comértelo también. Tiendo a creer que MRC impone una “disciplina” invalorable hacia la gestión de la memoria que todos se beneficiarían de tener. Pero también estoy de acuerdo en que el verdadero problema a tener en cuenta es la propiedad de objetos y los gráficos de objetos (como muchos han señalado), y no los recuentos de referencia de bajo nivel per se.

Para concluir: ARC NO es un pase gratuito para no tener en cuenta la memoria; es una herramienta para ayudar a los humanos a evitar tareas repetitivas, que causan estrés y son propensas al error, por lo tanto mejor delegadas a una máquina (el comstackdor, en este caso).

Dicho esto, personalmente soy una especie de artesano y aún no hice la transición. Acabo de empezar a usar Git …

ACTUALIZACIÓN: Así que migré todo mi juego, incluida la biblioteca gl, y sin problemas hasta el momento (excepto con el asistente de migración en Xcode 4.2). Si estás comenzando un nuevo proyecto, ve por él.

Lo he usado en un par de proyectos (ciertamente pequeños) y solo tengo buenas experiencias, tanto de rendimiento como de confiabilidad.

Una pequeña nota de precaución es que necesita aprender lo que debe hacer y lo que no: referencias débiles para no causar ningún bucle de referencia si usted mismo está codificando su UI, el diseñador tiende a hacer un buen trabajo. automáticamente si configura su GUI usándolo.

El único inconveniente que he encontrado es si utiliza una biblioteca con muchas funciones y datos de CoreFoundation. En MRC no tenía que preocuparse por utilizar un CFStringRef lugar de un NSString* . En ARC, debe especificar cómo interactúan los dos (puente básico? Liberar el objeto CoreFoundation y moverlo a ARC? Hacer un objeto Cocoa como un objeto retenido CoreFoundation +1?) Además, en OS X, solo está disponible en 64- código de bit (aunque tengo un encabezado que funciona alrededor de eso …).