Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

125
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda