delegates formato para - ¿Cómo puedo hacer una referencia de protocolo débil en Swift 'puro' (sin @objc)?





2 Answers

Respuesta suplementaria

Siempre estaba confundido acerca de si los delegados debían ser débiles o no. Recientemente he aprendido más sobre los delegados y cuándo usar referencias débiles, así que permítame agregar algunos puntos adicionales aquí para el futuro de los espectadores.

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

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

  • weak referencias weak siempre son opcionales (de lo contrario, se utilizaría unowned ) y siempre use var (no let ) para que el opcional se pueda establecer en nil cuando se desasigne.

  • Una clase padre debería naturalmente tener una referencia fuerte a sus clases secundarias y, por lo tanto, no usar la palabra clave weak . Sin embargo, cuando un niño desea una referencia a su padre, debe convertirla en una referencia débil mediante el uso de la palabra clave weak .

  • Debería usarse weak cuando desea una referencia a una clase que no posee, no solo para un niño que hace referencia a su padre. Cuando dos clases no jerárquicas necesitan hacer referencia una a la otra, elija una para ser débil. El que elijas depende de la situación. Vea las respuestas a esta pregunta para más información sobre esto.

  • 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 está utilizando 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 sólida.

  • Los protocolos se pueden utilizar tanto para los tipos de referencia (clases) como para los tipos de valor (estructuras, enumeraciones). Por lo tanto, en el caso probable de que necesite debilitar a un delegado, debe agregar la palabra clave de class al protocolo para que sepa que solo debe usarse 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 temas relacionados como la palabra clave unowned y los ciclos de referencia fuertes que ocurren con los cierres.

Relacionado

pedir referencias laborales

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 da un error de compilación ( weak no se puede aplicar a un tipo que no sea de clase MyClassDelegate ):

class MyClass {
  weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate {
}

Necesito prefijar el protocolo con @objc , entonces funciona.

Pregunta: ¿Cuál es la manera 'pura' y rápida de lograr un delegate weak ?




Actualización: Parece que el manual se ha actualizado y el ejemplo al que me refería se ha eliminado. Ver la edición de la respuesta de @ flainez arriba.

Original: utilizar @objc es la forma correcta de hacerlo, incluso si no está interoperando con Obj-C. Asegura que su protocolo se aplique a una clase y no a una enumeración o estructura. Consulte "Comprobación de la conformidad del protocolo" en el manual.




Related