guide basics swift automatic-ref-counting

basics - Hacerte débil en métodos en Swift



swift reference (4)

Ciertamente puedes construir una función para esto. No sé si lo hace dramáticamente mejor, pero es menos propenso a errores.

func methodPointer<T: AnyObject>(obj: T, method: (T) -> () -> Void) -> (() -> Void) { return { [unowned obj] in method(obj)() } } ... myCallbacks.append(methodPointer(self, CycleInducingClass.myInternalFunction))

Alternativamente, puede administrar sus devoluciones de llamada como punteros de método:

typealias Callback = (CycleInducingClass) -> () -> Void ... myCallbacks.append(CycleInducingClass.myInternalFunction)

En ese caso, deberías pasarte a ti self cuando los llamaste (lo que puede estar bien si no lo haces mucho):

self.myCallbacks[0](self)()

Todo esto se basa en el hecho de que un método en el tipo T con firma (input) -> (output) es equivalente a una función con la firma (T) -> (input) -> (output) .

En caso de que tenga curiosidad (lo estaba), la anulación funciona correctamente en este caso. Entonces, si subclasifica CycleInducingClass y reemplaza myInternalFunction , se myInternalFunction la versión correcta. (Eso realmente me sorprende un poco, y todavía no sé exactamente por qué funciona, pero sí lo hace).

EDIT: Aquí está la respuesta a eso: https://devforums.apple.com/message/1036509#1036509

Tengo una clase Swift que necesita almacenar una tabla de sus propios métodos. Desafortunadamente, esto está causando un ciclo de referencia, porque su tabla conserva las referencias a self través de los métodos que almacena.

Ejemplo de código con fugas a continuación:

typealias Callback = ()->() class CycleInducingClass : NSObject { var myCallbacks = [Callback]() override init() { super.init() myCallbacks.append(myInternalFunction) } func myInternalFunction() { NSLog("lolol: %d", self.myCallbacks.count) } }

La única solución que he encontrado hasta ahora es hacer esto:

myCallbacks.append({[unowned self] in self.myInternalFunction()})

Eso es bastante feo, y propenso a error. ¿Alguna idea mejor? ¿Hay algún truco para hacer que las propias referencias sean débiles? es decir, para hacer la matriz myCallbacks de tipo myCallbacks : [WeakCallback]() o algo así? Por lo que puedo decir, ni siquiera puedo construir una función de conveniencia weaken como azúcar sintáctica sobre el envoltorio de cierre feo arriba.


En Swift 4 (no estoy seguro de cuándo se hizo disponible la sintaxis), simplemente haga { [weak self] (params) in } para debilitarse. Básicamente es para [unowned self] , ¿qué Self? es para Self! . El compilador incluso requiere self?.foo lugar de self.foo .


La respuesta de Robs funcionó para mí. Lo refactoricé para que fuera un poco más OO, así que pensé que lo compartiría aquí en caso de que ayude a alguien más:

public protocol WeakCallback{ func invoke() } public class WeakCallbackInstance<T: AnyObject> : WeakCallback{ private let callback: ()->Void private weak var target: T? public init(target: T, action: (T)->()->Void){ self.target = target callback = { [weak target] in action(target!)() } } public func invoke(){ callback() } } class ExampleUsage{ func usage(){ var callbacks = [WeakCallback]() let one = WeakCallbackInstance(target: DummyCallbackOne(), action:DummyCallbackOne.callbackOne) let two = WeakCallbackInstance(target: DummyCallbackTwo(), action:DummyCallbackTwo.callbackTwo) callbacks.append(one) callbacks.append(two) callbacks.first?.invoke() } } class DummyCallbackOne{ func callbackOne(){ } } class DummyCallbackTwo{ func callbackTwo(){ } }


envuelto sin función param con bloque

myCallbacks.append({ [unowned self] in self.myInternalFunction() })

Función param envuelta con bloque

myCallbacks.append({ [unowned self] page in self.reloadData(page: page) })