2010-01-09 10 views

Respuesta

13

No, no lo hará, porque la desasignación no tiene el poder de cambiar el puntero. Solo podría hacer esto si pasó un puntero al puntero.

Si desea asegurarse de que está configurado en cero, debe hacerlo usted mismo.

Algunos consideran esta buena práctica, algunos lo consideran una pérdida de tiempo ya que su código debe estructurarse para no utilizar punteros después de la desasignación (hasta que se reasigne).

De hecho, me inclino hacia este último campo pero puedo ver por qué las personas quieren protegerse del acceso a la memoria liberada (programar a la defensiva rara vez es una mala idea).

+0

Configuro una macro para liberar un puntero de forma segura y configurarlo en 'nil'. – notnoop

+0

+1 FYI, cuando se utiliza la recolección de basura, los punteros '__weak' son" autocentrables ". Además, usar una macro para hacer esto puede ser propenso a errores, como menciono en mi respuesta a continuación. –

+1

Si no establece una referencia a cero cuando está liberando, Leaks no podrá decirle que hay una pérdida de memoria; después de todo, en lo que respecta a Leaks, tiene una referencia válida, aunque piense que la referencia ya no es válido (retención excesiva). –

2

No estoy seguro de si el puntero va a cero o si solo apunta a datos no válidos, pero es una buena convención de codificación para asignar sus variables a cero después de lanzarlas.

+0

+1 Este es un gran consejo, especialmente por ejemplo y variables estáticas, y doblemente bajo la recolección de elementos no utilizados, donde accidentalmente puede acumular referencias fuertes a la memoria innecesaria que no será reclamada como se desee. Creo que algunas personas solo quieren una solución mágica para que no tengan que pensar en este problema. –

1

Piense en esta situación:

void *p = malloc (100); 

while (someCondition) 
{ 
    // do something with p 
} 

free (p); 

// p is not set to NULL for you, it still points to where it always did 

Del mismo modo, cuando se cancela la asignación de un objeto de Objective-C, cualquier puntero a ese objeto siguen apuntando a donde estaba. Esto causa errores cuando otro objeto se asigna en el mismo espacio (o incluso si no se asigna nada al mismo espacio).

5

En el modelo de memoria de retención normal, no. Con la recolección de basura habilitada, esto sucede si el puntero se declara como __weak (para objetos Objective-C, el valor predeterminado es __strong). El recolector de basura pondrá a cero las referencias débiles cuando se eliminen, lo que las hace ideales para apuntar a delegados y objetos semi-transitorios. Vea también NSPointerArray, NSMapTable y NSHashTable y su apoyo para las relaciones débiles también. (NOTA: debe entenderse que una referencia débil no evitará que un objeto sea recolectado como basura, sino que se pone a cero cuando no hay referencias fuertes que apunten a la misma dirección. Consulte this document para obtener un breve resumen de este comportamiento.)

muchos otros beneficios para la recolección de basura de Objective-C, y sinceramente recomiendo usarlo si puedes. (Está disponible en OS X 10.5+, pero no en iPhone OS.) Las mejoras de rendimiento en Snow Leopard son más impresionantes, y para empezar, ya era bastante rápido.

Dicho esto, @darren tiene un buen punto: generalmente es una buena práctica anular sus propias variables al liberar sus contenidos. Si está buscando evitar punteros colgantes sobre objetos sobrevendidos, su mejor opción es adoptar el hábito de guardar la variable usted mismo. No incurrirá en tiempo de ejecución y es legible. Lo que es más importante, establecer variables a cero ayuda al sistema de recolección de basura a funcionar de manera más efectiva, ya que indica que la memoria puede recuperarse de manera segura. El código también funcionará perfectamente en ambos modos.

Sin embargo, en general, yo no nula a cabo valores en -dealloc desde la memoria que se está modificando está a punto de ser recuperada, y si alguna otra parte del código puede encontrar un error debido al uso de un valor liberado, para comenzar, no deberían estar usando un objeto desasignado. (Esto ocurre a menudo cuando un objeto no ha retenido correctamente a otro, y este último se desasigna, dejando un dangling pointer.) Las posibles excepciones a esto podrían incluir un corte por etapas donde las referencias no nulas podrían causar problemas dentro de dealloc, pero este tipo de comportamiento generalmente no ocurre (y no debería) al destruir un objeto.

Cuestiones relacionadas