在Swift中使自身变得脆弱 [英] Make self weak in methods in Swift

查看:72
本文介绍了在Swift中使自身变得脆弱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Swift类,需要存储自己的方法表.不幸的是,这导致了引用循环,因为它的表通过其存储的方法保留了对self的引用.

I have a Swift class that needs to store a table of its own methods. Unfortunately this is causing a reference cycle, because its table retains references to self via the methods it stores.

以下示例泄漏代码:

typealias Callback = ()->()

class CycleInducingClass : NSObject {
    var myCallbacks = [Callback]()  

    override init() {
        super.init()
        myCallbacks.append(myInternalFunction)
    }

    func myInternalFunction() {
        NSLog("lolol: %d", self.myCallbacks.count)
    }
}

到目前为止,我发现的唯一解决方案是改为执行此操作:

The only solution I've found so far is to instead do this:

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

这很丑陋,而且容易出错.还有更好的主意吗?是否有一些使函数引用本身变弱的技巧?即使myCallbacks类型为myCallbacks : [WeakCallback]()的数组?据我所知,我什至无法在上面的丑陋的封套包装上建立方便功能weaken作为语法糖.

That's pretty ugly, and prone to error. Any better ideas? Is there some trick for making the function references themselves be weak? i.e. to make the myCallbacks array of type myCallbacks : [WeakCallback]() or something? As far as I can tell I can't even build a convenience function weaken as syntactic sugar over the ugly closure wrapper above.

推荐答案

您当然可以为此构建一个函数.我不知道它是否可以使它变得更好,但是它不容易出错.

You can certainly build a function for this. I don't know if it makes it dramatically better, but it is less error-prone.

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

或者,您可以将回调作为方法指针进行管理:

Alternately, you could manage your callbacks as method pointers:

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

在这种情况下,您需要在调用它们时传递self(如果您实际上不做很多事情,这可能会很好):

In that case, you'd need to pass self when you called them (which may be fine if you don't actually do this a lot):

self.myCallbacks[0](self)()

所有这些基于以下事实:签名为(input) -> (output)的类型为T的方法等效于签名为(T) -> (input) -> (output)的函数.

All of this is based on the fact that a method on type T with signature (input) -> (output) is equivalent to a function with the signature (T) -> (input) -> (output).

如果您好奇(我曾经),那么在这种情况下,重写可以正常工作.因此,如果子类CycleInducingClass并覆盖myInternalFunction,则将调用正确的版本. (这实际上让我感到有些惊讶,但我还不知道它为什么起作用,但确实如此.)

In case you're curious (I was), overriding works correctly in this case. So if you subclass CycleInducingClass and override myInternalFunction, the correct version will be called. (That actually surprises me a little, and I don't yet know exactly why it works, but it does.)

这是答案: https://devforums.apple.com/message/1036509#1036509

这篇关于在Swift中使自身变得脆弱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆