Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

127
Vistas
La referencia de vista débil no se desasignará después de agregarse temporalmente a la jerarquía de vista

Me encontré con lo más raro, tal vez alguien tenga una explicación. Pasos:

  1. Crear una UIView A
  2. Crear una referencia débil a A
  3. Agregar A a la jerarquía de vistas
  4. Eliminar A de la jerarquía de vistas
  5. Establecer A en cero
  6. La referencia débil todavía existe.

Si omite los pasos 3 y 4, la referencia débil se vuelve nula como se esperaba.

Código para probar:

TestView para comprobar deinit

 class TestView: UIView { deinit { print("deinit") } }

Prueba de unidad

 class RetainTests: XCTestCase { func testRetainFails() { let holderView = UIView() var element: TestView? = TestView() holderView.addSubview(element!) element?.removeFromSuperview() weak var weakElement = element XCTAssertNotNil(weakElement) // after next line `weakElement` should be nil element = nil // console will print "deinit" XCTAssertNil(weakElement) // fails! } func testRetainPasses() { var element: TestView? = TestView() weak var weakElement = element XCTAssertNotNil(weakElement) // after next line `weakElement` should be nil element = nil // console will print "deinit" XCTAssertNil(weakElement) } }

Ambas pruebas imprimirán deinit en la consola, pero en el caso de que falle la prueba, el weakElement aún conserva la referencia si el element estuvo en una jerarquía de vista en algún momento, aunque el element se desasignó con éxito. ¿Como puede ser?

(Editar: esto está dentro de una aplicación, NO un patio de recreo)

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Hay un lanzamiento automático adjunto a TestView cuando lo agrega y lo elimina de la supervista. Si se asegura de drenar el grupo de liberación automática, esta prueba se comporta como espera:

 autoreleasepool { holderView.addSubview(element!) element?.removeFromSuperview() }

Dicho esto, no puedes confiar en este comportamiento. No hay ninguna promesa sobre cuándo se destruirá un objeto. Solo sabe que será después de que publique su última referencia fuerte a él. Puede haber retenciones o liberaciones automáticas adicionales en el objeto. Y no hay ninguna promesa de que se llamará a deinit , así que definitivamente asegúrese de no poner ninguna lógica obligatoria allí. Solo debe realizar la limpieza de la memoria. (Tanto Mac como iOS, por razones ligeramente diferentes, nunca llamen a deinit durante la finalización del programa).

En su caso de prueba fallido, deinit se imprime después de que falla la afirmación. Puede demostrar esto colocando puntos de interrupción en la aserción fallida y la print . Esto se debe a que el grupo de liberación automática se vacía al final del caso de prueba.

La lección subyacente es que es muy común que las llamadas de retención/liberación automática equilibradas se coloquen en un objeto que se pasa al código ObjC (y UIKit es en gran medida ObjC). Por lo general, no debe esperar que los objetos UIKit se destruyan antes del final del ciclo de eventos actual. No confíe en eso (no se promete), pero a menudo es cierto.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda