Todavía tengo que usar ARC, ya que la mayor parte del código del proyecto en el que estoy trabajando en este momento fue escrito antes de iOS 5.0.
Me estaba preguntando, ¿la conveniencia de no retener / liberar manualmente (y presumiblemente un código más confiable que viene como resultado) supera cualquier "costo" de usar ARC? ¿Cuáles son sus experiencias con ARC y lo recomendaría?
Entonces:
- ¿Cuánto beneficio puede aportar ARC a un proyecto?
- ¿ARC tiene un costo como la recolección de basura en Java?
- ¿Ha estado usando ARC y, de ser así, cómo lo ha encontrado hasta ahora?
iphone
objective-c
ipad
ios5
automatic-ref-counting
Simon Withington
fuente
fuente
Respuestas:
No hay inconveniente. Úselo. Hazlo hoy. Es más rápido que su código anterior. Es más seguro que su código anterior. Es más fácil que tu código anterior. No es recolección de basura. No tiene sobrecarga de tiempo de ejecución de GC. Las inserciones del compilador retienen y liberan 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.)
Bien, ahora les contaré los pequeños inconvenientes:
Si es un desarrollador de ObjC desde hace mucho tiempo, se contraerá durante aproximadamente una semana cuando vea el código ARC. Lo superarás muy rápidamente.
Hay algunas (muy) pequeñas complicaciones en la conexión al código de Core Foundation. Hay poco más complicaciones en el trato con todo lo que trata una
id
comovoid*
. Cosas como las matrices C deid
pueden requerir un poco más de reflexión para hacerlas correctamente. El manejo elegante de ObjCva_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ía tener mucho de esto en cualquier caso.No se puede poner
id
en unastruct
. Esto es bastante raro, pero a veces se usa para empaquetar datos.Si no siguió la denominación correcta de KVC y mezcla código ARC y no ARC, tendrá problemas de memoria. ARC utiliza la denominación KVC para tomar decisiones sobre la gestión de la memoria. Si todo es código ARC, entonces no importa porque hará lo mismo "mal" en ambos lados. Pero si se trata de una mezcla ARC / no ARC, entonces hay una falta de coincidencia.
ARC perderá memoria durante los lanzamientos de excepción de ObjC. Una excepción de ObjC debe estar muy cerca de la finalización de su programa. Si detecta una cantidad significativa de excepciones de ObjC, las está usando incorrectamente. Esto se puede arreglar usando
-fobjc-arc-exceptions
, pero incurre en las sanciones que se describen a continuación:ARC no perderá memoria durante las excepciones de ObjC o C ++ en código ObjC ++, pero esto es a costa del rendimiento de tiempo y espacio. Esta es otra de 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
los punteros no funcionan correctamente en iOS 4 o Mac OS X 10.6, lo cual es una pena, pero es bastante fácil de solucionar.__weak
Los consejos son geniales, pero no son el punto de venta número uno de ARC.Para más del 95% del código, ARC es brillante y no hay ninguna razón para evitarlo (siempre que pueda manejar las restricciones de la versión del sistema operativo). Para el 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ía mover código que no es ARC a un xcodeproj separado para simplificar esto.En conclusión, cambie a ARC tan pronto como pueda y nunca mire atrás.
EDITAR
He visto un par de comentarios en la línea de "usar ARC no sustituye a conocer las reglas de administración de memoria de Cocoa". Esto es mayormente cierto, pero es importante entender por qué y por qué no. Primero, si todo su código usa ARC y viola las Tres Palabras Mágicaspor todas partes, todavía no tendrás problemas. Es impactante decirlo, pero ahí lo tienes. ARC puede retener algunas cosas que no querías que retenga, pero también las liberará, 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 reales de administración de la memoria, y probablemente solo mencionaría las reglas de administración de la memoria para nombrar al hablar sobre los nombres de KVC. Con ARC, creo que podría convertirse en un programador principiante decente sin tener que aprender las reglas de administración de la memoria.
Pero no podrías convertirte en un programador intermedio decente. Necesita conocer las reglas para conectarse correctamente con Core Foundation, y cada programador intermedio necesita lidiar con CF en algún momento. Y necesita conocer las reglas para el código ARC / MRC mixto. Y necesita conocer las reglas cuando empiece a jugar con los
void*
punterosid
(que sigue necesitando para realizar KVO correctamente). Y bloques ... bueno, la gestión de la memoria en bloque es simplemente extraña.Entonces, mi punto es que la administración de la memoria subyacente sigue siendo importante, pero donde solía pasar mucho tiempo estableciendo y reformulando las reglas para los nuevos programadores, 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()
.fuente
Llegarán respuestas mejores y más técnicas que las mías, pero aquí va:
fuente
El beneficio es un grado significativo de protección contra errores comunes de administración de memoria. Las fugas causadas por no liberar un objeto y los choques por no retener o liberar prematuramente un objeto deben reducirse significativamente. Aún necesita comprender el modelo de memoria contada de referencia para poder clasificar sus referencias como fuertes o débiles, evitar ciclos de retención, etc.
No hay recolección de basura en iOS. ARC es similar a GC en que no tiene que retener o liberar objetos manualmente. Es diferente a GC en que no hay recolector de basura. El modelo de retención / liberación aún se aplica, es solo que el compilador inserta las llamadas de administración de memoria adecuadas en su código en el momento de la compilación.
Es un poco desconcertante si está acostumbrado al conteo de referencias, pero eso es solo una cuestión de acostumbrarse y aprender a confiar en que el compilador realmente hará lo correcto. Se siente como una continuación del cambio a las propiedades que venía 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 versiones anteriores de iOS, por lo que debe tenerlo en cuenta antes de decidir adoptarlo.
fuente
Creo que ARC es una gran idea. En comparación con GC, puedes tener tu pastel y comértelo también. Tiendo a creer que MRC impone una "disciplina" invaluable hacia la gestión de la memoria que todos se beneficiarían de tener. Pero también estoy de acuerdo en que el problema real 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 libre 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 a errores, por lo que es mejor delegarla en una máquina (el compilador, en este caso).
Dicho esto, personalmente soy una especie de artesano y aún no he hecho la transición. Acabo de empezar a usar Git ...
ACTUALIZACIÓN: Así que migré todo mi juego, incluida la biblioteca gl, y hasta ahora no tuve problemas (excepto con el asistente de migración en Xcode 4.2). Si está comenzando un nuevo proyecto, hágalo.
fuente
Lo he usado en un par de proyectos (ciertamente pequeños), y solo tengo buenas experiencias, tanto en rendimiento como en confiabilidad.
Una pequeña nota de precaución es que debe aprender lo que se debe hacer y lo que no se debe hacer de las referencias débiles para no causar ningún bucle de referencia si está codificando su interfaz de usuario usted mismo, el diseñador tiende a hacer un buen trabajo. automáticamente si configura su GUI usándola.
fuente
El único inconveniente que he encontrado es si usa una biblioteca con muchas funciones y datos de CoreFoundation. En MRC no tenía que preocuparse por usar un en
CFStringRef
lugar de unNSString*
. 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 +1 CoreFoundation?) Además, en OS X, solo está disponible en 64- código de bits (aunque tengo un encabezado que funciona alrededor de eso ...).fuente