¿Cómo puedo hacer una referencia de protocolo débil en Swift 'pura' (sin @objc)



Answers

Respuesta suplementaria

Siempre estaba confundido acerca de si los delegados deberían ser débiles o no. Recientemente aprendí más sobre los delegados y cuándo utilizar referencias débiles, así que permítanme agregar algunos puntos suplementarios aquí por el bien de los futuros espectadores.

  • El propósito de usar la palabra clave weak es evitar ciclos de referencia fuertes (conservar ciclos). Los ciclos de referencia fuertes ocurren cuando dos instancias de clases tienen referencias fuertes entre sí. Sus recuentos de referencia nunca llegan a cero, por lo que nunca se desasignan.

  • Solo necesitas usar weak si el delegado es una clase. Las estructuras y enumeraciones Swift son tipos de valores (sus valores se copian cuando se realiza una nueva instancia), no tipos de referencia, por lo que no hacen fuertes ciclos de referencia .

  • weak referencias weak son siempre opcionales (de lo contrario se usaría unowned ) y siempre se usa var (no let ) para que la opción opcional se pueda establecer como nil cuando se desasigna.

  • Una clase principal naturalmente debería tener una referencia fuerte a sus clases secundarias y, por lo tanto, no usar la palabra clave weak . Sin embargo, cuando un niño quiere una referencia a su padre, debe hacer que sea una referencia débil usando la palabra clave weak .

  • weak debe usarse cuando desee una referencia a una clase que no le pertenece, no solo para un niño que hace referencia a su padre. Cuando dos clases no jerárquicas necesitan referenciar entre sí, elija una para ser débil. El que elijas depende de la situación. Vea las respuestas a esta pregunta para obtener más información al respecto.

  • Como regla general, los delegados deben marcarse como weak porque la mayoría de los delegados hacen referencia a clases que no son de su propiedad. Esto es definitivamente cierto cuando un niño usa un delegado para comunicarse con un padre. Sin embargo, todavía hay algunas situaciones en las que un delegado puede y debe usar una referencia fuerte.

  • Los protocolos se pueden usar para ambos tipos de referencia (clases) y tipos de valor (estructuras, enumeraciones). Por lo tanto, en el caso probable de que necesite hacer que un delegado sea débil, debe agregar la palabra clave class al protocolo para que sepa que solo se debe usar con tipos de referencia.

    protocol MyClassDelegate: class {
        // ...
    }
    
    class SomeClass {
        weak var delegate: MyClassDelegate?
    }
    

Estudio adicional

Leer los siguientes artículos es lo que me ayudó a entender esto mucho mejor. También discuten problemas relacionados como la palabra clave unowned y los fuertes ciclos de referencia que ocurren con los cierres.

Relacionado

Question

weak referencias weak no parecen funcionar en Swift a menos que un protocol se declare como @objc , que no quiero en una aplicación Swift pura.

Este código proporciona un error de compilación ( weak no se puede aplicar al tipo de clase MyClassDelegate ):

class MyClass {
  weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate {
}

Necesito prefijar el protocolo con @objc , luego funciona.

Pregunta: ¿Cuál es la forma "pura" de Swift de lograr un delegate weak ?




AnyObject es la forma oficial de usar una referencia débil en Swift.

class MyClass {
    weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate: AnyObject {
}

De Apple:

Para evitar fuertes ciclos de referencia, los delegados deben declararse como referencias débiles. Para obtener más información sobre referencias débiles, vea Ciclos de referencia potentes entre instancias de clase. Al marcar el protocolo como de solo clase, más adelante podrá declarar que el delegado debe usar una referencia débil. Marca un protocolo como de solo clase heredando AnyObject , como se explica en los Protocolos de clase solamente.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276




Related