Swift,带闭包的观察者模式

Swift, Observer pattern with closures

我试图在 swift 中仅使用函数来实现观察者模式:

var closures: [() -> Void] = []

class A: NSObject
{
    static var c = 0
    var i = 0

    override init()
    {
        super.init()
        self.i = A.c
        A.c += 1
    }

    func foo()
    {
        print("Hi: \(i)")
        print("\(A.c)")
    }
} // class

var aa:A? = A()

closures.append(aa!.foo)

for item in closures
{
    item()
}

aa = A()

for item in closures
{
    item()
}

这会打印:

Hi: 0
1
Hi: 0
2

第一个问题,实例变量i好像从来没有被修改过,你知道为什么吗?

第二个问题,会不会泄露内存?由于我有一个函数数组,aa是否会在不清空数组的情况下被释放?

第三个问题,对于仅使用函数的观察模式有更好的想法吗? (我不想使用协议)

您误解了 retain/release 循环。让我们逐行浏览您的代码:

var aa:A? = A()

初始化 A 的新实例。此内存的保留计数为 1。

closures.append(aa!.foo)

A 的实例附加到 closures 数组。保留计数为 2。

for item in closures
{
    item()
}

A 的第一个实例上调用 foo

aa = A()

创建 A 的另一个实例。第一个实例继续被数组保留,保留计数下降到 1。但是 A.c 递增,因为您在 init 方法中对其进行了编码。

for item in closures
{
    item()
}

您仍在调用第一个对象的方法。 A.c 与第二个对象共享,但 i 不是。第二个对象永远不会在 closures 数组中。

在回答您的其他问题之前:您为什么要尝试这样做?

我在 google 上找到了使用 better 关键字的解决方案。 我需要使用闭包来实现观察者模式,以避免协议,从而将观察者与可观察对象解耦。 observer 是一个对象,带有这样一个闭包数组: var array:[() -> ()] = []

每个observable将它的函数添加到这个数组中,当需要时观察者将调用这个数组的每个或任何函数。 功能制作如下图

lazy var someClosure: () -> String = { [unowned self, ] in // closure body goes here } 为避免保留循环,必须将 self 捕获为 unowedweak.

这是一篇更详细地解释这个解决方案的文章:https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b#.dmijmxbc4