wxs*_*wxs 25 automatic-ref-counting swift
我有一个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)
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我找到的唯一解决方案是改为:
myCallbacks.append({[unowned self] in self.myInternalFunction()})
Run Code Online (Sandbox Code Playgroud)
这很丑陋,容易出错.有更好的想法吗?是否有一些技巧使函数引用本身变弱?即制作myCallbacks类型myCallbacks : [WeakCallback]()或类似的数组?据我所知,我甚至无法weaken在上面丑陋的闭包装上构建一个方便函数作为语法糖.
Rob*_*ier 13
你当然可以为此建立一个功能.我不知道它是否会使它变得更好,但它不容易出错.
func methodPointer<T: AnyObject>(obj: T, method: (T) -> () -> Void) -> (() -> Void) {
return { [unowned obj] in method(obj)() }
}
...
myCallbacks.append(methodPointer(self, CycleInducingClass.myInternalFunction))
Run Code Online (Sandbox Code Playgroud)
或者,您可以将回调作为方法指针进行管理:
typealias Callback = (CycleInducingClass) -> () -> Void
...
myCallbacks.append(CycleInducingClass.myInternalFunction)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,self当你打电话给他们时你需要通过(如果你实际上没有这么做的话可能没问题):
self.myCallbacks[0](self)()
Run Code Online (Sandbox Code Playgroud)
所有这一切都基于以下事实:T带有签名的类型的方法(input) -> (output)等同于具有签名的函数(T) -> (input) -> (output).
如果你很好奇(我是),在这种情况下,覆盖正常工作.因此,如果您进行子类化CycleInducingClass和覆盖myInternalFunction,则将调用正确的版本.(这实际上让我感到惊讶,我还不知道它为什么会起作用,但确实如此.)
编辑:这是答案:https://devforums.apple.com/message/1036509#1036509
| 归档时间: |
|
| 查看次数: |
3418 次 |
| 最近记录: |