方法引用使对象在 Swift 中保持活动状态

Method reference keeps object alive in Swift

我注意到一些对对象方法的引用会创建对该对象的强引用并使其在 Swift 中保持活动状态。

有什么解决办法吗?是否可以将方法引用标记为弱?

class Counter
{
    var n: Int = 0

    func inc() -> Int
    {
        n += 1
        return n
    }
}

var o: Counter? = Counter()
weak var w: Counter? = o
var c: () -> (Int) = o!.inc

c() // 1
w?.n

o = nil

c() // 2 - object is still alive here
w?.n // weak reference is also alive here

var c 不是对方法的引用,它是对 closure 的引用 - 方法包以及它需要对其进行操作的任何对象。在你的例子中,方法 inc 需要它的 Counter 对象来完成它的工作,所以 Counter 保持活动状态。

让对象保持活动状态的闭包是一项基本功能。释放对象的唯一方法是显式释放对其实例方法的所有引用。

您不能创建闭包引用 weak 但您可以将其设为可选。

class Counter
{
    var n: Int = 0

    func inc() -> Int
    {
        n += 1
        return n
    }
}

var o: Counter? = Counter()
weak var w: Counter? = o
var c: (() -> (Int))? = o?.inc //this is the crucial part

c?() // 1
w?.n

o = nil
c = nil

c?() //nil
w?.n //nil

这是你想要做的吗?
我注意到金属示例应用程序在闭包中的引用很弱。

class Counter
{
    var n: Int = 0

    func inc() 
    {
        n += 1
        print("new count \(n)")
    }

    deinit { 
        print("deinit")
    }
}

var counter: Counter? = Counter()

var closure: () -> ()  = {
    [weak counter] in
        if let strongRef = counter {
            print("alive")
            strongRef.inc()
        } else {
            print("dead")
        }
}

closure()
counter = nil
closure()

这会打印

alive
new count 1
deinit
dead