delegate delegado swift delegates weak-references

delegate - delegado swift



Delegación Swift: cuándo utilizar el puntero débil en un delegado (3)

¿Puede alguien explicar cuándo y cuándo no usar una asignación ''débil'' a un puntero de delegado en Swift, y por qué?

Según entiendo, si usa un protocolo que no está definido como una clase, no puede, ni desea, asignarle a su delegado un puntero débil.

protocol MyStructProtocol{ //whatever } struct MyStruct { var delegate: MyStructProtocol? }

Sin embargo, cuando su protocolo se define como un protocolo de tipo de clase, ¿DESEA establecer su delegado en un puntero débil?

protocol MyClassProtocol:Class{ //whatever } class MyClass { weak var delegate: MyClassProtocol? }

¿Estoy en lo correcto? En la guía rápida de Apple, los ejemplos de protocolo de clase no utilizan asignaciones débiles, pero en mis pruebas veo fuertes ciclos de referencia si mis delegados no tienen una referencia débil.


Los delegados deben (editar: generalmente) ser siempre débiles.

Digamos que b es el delegado de a . Ahora la propiedad de un delegate es b .

En un caso en el que desea que b libere cuando c se ha ido

Si c contiene una referencia fuerte a b y c desasigna, usted quiere desasignar con c . Sin embargo, usar una propiedad de delegado fuerte en a , b nunca será desasignada ya que a se aferra fuertemente a b . Usando una referencia débil, tan pronto como b pierda la referencia fuerte de c , b se destrabará cuando c deallocs.

Por lo general, este es el comportamiento previsto, por lo que es conveniente usar una propiedad weak .


Por lo general, los protocolos de clase (como se define con class palabra clave class ) son débiles para evitar el riesgo de un "ciclo de referencia fuerte" (conocido anteriormente como "ciclo de retención"). El hecho de no hacer que el delegado sea débil no significa que tengas inherentemente un ciclo de referencia fuerte, sino simplemente que puedas tener uno.

Sin embargo, con los tipos de struct , el fuerte riesgo del ciclo de referencia se ve enormemente disminuido porque los tipos de struct no son tipos de "referencia", por lo que es más difícil crear un ciclo de referencia fuerte. Pero si el objeto delegado es un objeto de clase, entonces es posible que desee convertir el protocolo en un protocolo de clase y debilitarlo.

En mi opinión, hacer que los delegados de la clase sean débiles es solo parcialmente para aliviar el riesgo de un fuerte ciclo de referencia. Es realmente una cuestión de "propiedad". La mayoría de los protocolos de delegado son situaciones en las que el objeto en cuestión no tiene derecho a reclamar propiedad sobre el delegado, sino simplemente cuando el objeto en cuestión proporciona la capacidad de informar al delegado de algo (o solicitar algo de eso).


protocol MyDelegate: class { // ... } class MyViewController: UIViewController { weak var delegate: MyDelegate? }