我有一个Swift类,需要存储自己的方法表。不幸的是,这导致了一个引用循环,因为它的表self
通过它存储的方法保留了对它们的引用。
以下示例泄漏代码:
typealias Callback = ()->()
class CycleInducingClass : NSObject {
var myCallbacks = [Callback]()
override init() {
super.init()
myCallbacks.append(myInternalFunction)
}
func myInternalFunction() {
NSLog("lolol: %d", self.myCallbacks.count)
}
}
到目前为止,我发现的唯一解决方案是改为执行此操作:
myCallbacks.append({[unowned self] in self.myInternalFunction()})
这很丑陋,而且容易出错。还有更好的主意吗?是否有一些使函数引用本身变弱的技巧?即使myCallbacks
类型的数组myCallbacks : [WeakCallback]()
或什么?据我所知,我什至无法weaken
在上述丑陋的封闭包装上构建作为语法糖的便捷功能。
您当然可以为此构建一个函数。我不知道它是否可以使它变得更好,但是它不容易出错。
func methodPointer<T: AnyObject>(obj: T, method: (T) -> () -> Void) -> (() -> Void) {
return { [unowned obj] in method(obj)() }
}
...
myCallbacks.append(methodPointer(self, CycleInducingClass.myInternalFunction))
或者,您可以将回调作为方法指针进行管理:
typealias Callback = (CycleInducingClass) -> () -> Void
...
myCallbacks.append(CycleInducingClass.myInternalFunction)
在这种情况下,您需要self
在呼叫他们时通过(如果您实际上不做很多事情,那可能会很好):
self.myCallbacks[0](self)()
所有这些都是基于这样一个事实,即T
带有签名的类型方法(input) -> (output)
等同于带有签名的函数(T) -> (input) -> (output)
。
万一您好奇(我曾经),在这种情况下,覆盖可以正常工作。因此,如果您子类化CycleInducingClass
并重写myInternalFunction
,则会调用正确的版本。(这实际上让我感到有些惊讶,但我还不知道它为什么起作用,但确实如此。)
编辑:这是答案:https : //devforums.apple.com/message/1036509#1036509
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句