objective-c memory-management null

objective c - Release, Dealloc y the Self reference



objective-c memory-management (5)

A4) Se diferencian en sus tipos. Todos son cero, pero NULL es un vacío *, nil es una identificación y Nil es un puntero de clase.

Así que pensé que tenía todas estas preguntas todas resueltas. Entonces, de repente, recibo un error (un bloqueo) que no puedo entender. Luego, después de investigar para remediar el accidente, noto que todo lo que creía saber sobre estas áreas críticas es algo erróneo.

A continuación hay 8 preguntas que voy a lanzar por ahí con la esperanza de que alguien conteste: las respuestas a estas preguntas me ayudarán a recuperar mi comprensión. Gracias de antemano!

Q1) ¿Está bien invocar Release en un objeto si esa referencia es nula? Esto debería ser inofensivo, ¿verdad?

Q2) ¿Está bien invocar Release en un objeto si esa referencia se ha liberado y como un recuento de referencia de 0?

Q3) ¿Es necesario establecer una referencia a nula DESPUÉS de soltarlo? ¿Qué pasa si no lo configuras a cero?

Q4) ¿Existe realmente una diferencia entre nulo y NULL, o es solo una cuestión semántica ayudar al lector / desarrollador a conocer el tipo de objeto con solo echarle un vistazo?

Q5) ¿El uso de propiedades REQUIERE el uso del puntero ''Self''?

Q6) El uso de variables de instancia requiere que el puntero ''Self'' NO se use?

P7) ¿Cuándo querría usar una variable de instancia en lugar de su propiedad? Me imagino que los miembros de datos de tipo de valor están bien, ya que no están liberando y manteniendo involucrados.

Q8) ¿Es necesario llamar a dealloc de un objeto desde la función dealloc? En muchos ejemplos, he visto que se llama a Release, pero no a Dealloc. ¿Son incorrectos estos tutoriales?


De acuerdo. He confirmado que no configurar B a nil hizo el truco. Entonces, ahora, no compruebo nada cuando creo el controlador B (cuando quiero navegar hacia él).

En cambio, lanzo B, luego creo el controlador y lo asigno a B. Luego, en el método viewDidAppear de A, lanzo B.

Creo que este hilo ahora está cerrado. ¡Gracias!


Otros han respondido 1-6 adecuadamente.

(7) Apple recomienda usar la variable de instancia directamente en init y dealloc. Principalmente esto se debe a que el objeto (especialmente si está subclasificado) está configurado solo parcialmente durante estos dos métodos, por lo que llamar a setters / getters puede dar como resultado un comportamiento incorrecto si tienen algo más que acciones triviales. En general, puede acceder de manera segura al ivar directamente (en lugar de a través del getter) en su objeto, y será marginalmente más eficiente para hacerlo (solo relevante en el iPhone). En general, debe usar el colocador en todos los casos, especialmente si su objeto puede estar subclasificado o si otros pueden estar observando la propiedad.

(8) Nunca, nunca, llame a dealloc (excepto [super dealloc] desde dentro del método dealloc). Si tiene una propiedad sobre otro objeto, entonces debe renunciar a esa propiedad (llamando al lanzamiento o a la liberación automática). El sistema llamará a dealloc sobre el objeto si corresponde. Pero nunca llamas a dealloc tú mismo. Lea las reglas de administración de memoria (son solo 9 párrafos y es vital para entender).


Probablemente deberías haber dividido esta pregunta en varias preguntas diferentes, pero voy a morder.

  1. Sí, cualquier mensaje enviado a nil es un no-op.
  2. No. Se ha destruido, o se destruirá inminentemente, un objeto con recuento de refinanciación y cualquier mensaje que se le envíe provocará un bloqueo o, en el mejor de los casos, una excepción.
  3. Depende de la situación. Si estás liberando cosas en -dealloc , entonces probablemente no. Si se trata de un objeto que tiene un alcance determinado para un método en particular, entonces probablemente no. Si se trata de un ivar reutilizado, diría que sí. En los primeros dos casos, no pasará nada si no configura los punteros a cero, ya que normalmente ya no podrá acceder a esos punteros. Sin embargo, en el último caso, aún puede acceder al puntero, que apunta a la memoria desasignada. Si le envía un mensaje o intenta desreferenciarlo, su aplicación se bloqueará.
  4. Ambos son iguales a 0. Por convención, nil se usa para punteros a objetos, y NULL se usa para cualquier otro puntero, pero mezclarlos no causará ningún problema.
  5. Si desea invocar la propiedad getter / setter, entonces sí. Si desea acceder al ivar, encapsula directamente (poco común), no.
  6. No, puede acceder a variables de instancia usando la sintaxis self->ivar . De hecho, cuando escribe solo ivar , el compilador agrega implícitamente la self-> desreferenciación.
  7. No estoy seguro de lo que quieres decir aquí.
  8. La única vez que deberías llamar -dealloc es cuando llamas [super dealloc]; en tus propios métodos de -dealloc . Para cualquier otro objeto, siempre deberías llamar " -release .

A1) [nil release] está bien (no hará nada)

A2) No. No toques objetos después de que hayan sido desasignados. Deben establecerse en cero después de que se liberen.

A3) No es necesario establecer un puntero liberado en cero, pero se obtienen punteros colgantes (es decir, no se puede decir si un objeto es válido o no). Establecer una propiedad a cero se utiliza a menudo para liberar el ivar subyacente, por lo que no hacerlo puede causar una pérdida de memoria

A4) nulo y NULL son ambos cero, por lo que técnicamente son los mismos.

A5) Sí, debe usar self.someProperty para las propiedades, del mismo modo que usaría [self someProperty] si fuera solo un método

A6) self es esencialmente una estructura, por lo que puedes acceder a ivars como así: self->someIvar . No es necesario, sin embargo.

A7) Cuando no desea ejecutar los métodos setter / getter por cualquier razón. Lo uso ocasionalmente cuando el colocador no permite valores nulos, y necesito liberar la variable

A8) se llama automáticamente a dealloc cuando la liberación se llama la cantidad correcta de veces. Nunca debe llamar a dealloc directamente (a excepción de [super dealloc])