Gestión de memoria rápida: almacenamiento de funciones en var

Estoy buscando la mejor práctica para almacenar funciones como variables en otros objetos. Específicamente, estoy buscando evitar los ciclos de retención inherentes a la capturaself en la función

Viniendo del objetivo-c y los bloques, normalmente haría algo como esto:

__weak id _self = self;
iVar.someBlock = ^{
    [_self doSomething];
};

Por supuesto, eliVar La clase copiaría el bloque y lo almacenaría. No existe un ciclo de retención porque he capturado__weak id _self.

En Swift, estoy un poco menos seguro, especialmente porque puedo pasar funciones / métodos de clase. Entonces, digamos en eliVar clase que tengo:

class iVarClass {
    var callBack:() -> ()?
    func jumpUpAndDown(){
        //Weeeeeee!
        self.callBack?()
    }
}

Ahora en mi clase "principal" tengo una variable de instancia de la clase anterior y hago:

class mainClass {
    var iVar: iVarClass
    init(iVar:iVarClass){
        self.iVar = iVar
        iVar.callback = self.doSomething
    }
    func doSomething(){
      self.iVar.jumpUpAndDown?()
    }
}

¿Tenemos un ciclo de retención aquí? Creo que sí, y creo que tal vez necesito hacer elcallback débiles:

    weak var callBack:() -> ()?

Por supuesto, podría hacer algo como esto en la clase principal:

    init(iVar:iVarClass){
        self.iVar = iVar
        weak var _self = self
        iVar.callback = {
            _self?.doSomething()
        }
    }

¡Pero es muy bueno poder pasar funciones de clase como argumentos! Además, si necesito hacer elcallback débil, entonces creo que perdería la capacidad de asignarle un cierre (porque después de la asignación, el cierre se liberaría de la memoria con solo una referencia débil).

Además, observe cómo la responsabilidad de la gestión de la memoria recae ahora en el receptor en lugar del asignador, pero dado que el receptor no puede conocer el origen de la asignación, realmente no puede ser considerado responsable. En otras palabras, ahora debe haber un contrato implícito entre el receptor y el cesionario sobre qué tipo de función se va a pasar, que es frágil y no se recomienda. Cuando el cesionario es responsable, puede tomar medidas para garantizar que no haya un ciclo de retención, pero el receptor no puede tomar esas medidas.

Esto me hace pensar que deberíamosNunca pasar una función de clase a otro objeto. Es muy peligroso. No puede saber cómo lo almacenará / usará el receptor.

¿O me estoy perdiendo algo? ¿Swift resuelve mágicamente este problema detrás de escena?

Actualizar

@ Kirsteins señaló algo que había olvidado: listas de captura. Entonces, en lugar de declarar explícitamenteweak var _self = self, Puede declararlo en el cierre en su lugar:

    init(iVar:iVarClass){
        self.iVar = iVar
        iVar.callback = { [weak self] in
            self?.doSomething()
        }
    }

Esto es mejor, pero no tan elegante como simplemente asignar la función de clase.

Pienso lo que yoquerer es para Swift para convertir automáticamente una función de clase en un cierre con una lista de captura para que no tenga que hacerlo. Para ser justos, no es exactamente difícil, pero ciertamente es mucho más bonito si solo pudiera asignar la función de clase. Demonios, incluso esto sería mejor:

self.iVar.callback = weak self.doSomething

Respuestas a la pregunta(1)

Su respuesta a la pregunta