Swift,Observer模式与闭包

时间:2016-08-28 17:21:26

标签: swift design-patterns observer-pattern

我正在尝试仅使用函数在swift中实现Observer模式:

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是否会在不清空数组的情况下被释放?

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

2 个答案:

答案 0 :(得分:1)

您误解了保留/释放周期。让我们逐行浏览您的代码:

var aa:A? = A()

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

closures.append(aa!.foo)

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

for item in closures
{
    item()
}

foo的第一个实例上调用A

aa = A()

创建A的另一个实例。第一个实例继续由数组保留,并且保留计数降至1.但A.c会增加,因为您使用init方法对其进行了编码。

for item in closures
{
    item()
}

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

在我提出其他问题之前:你为什么要这么做?

答案 1 :(得分:0)

我在google上使用更好的关键字找到了解决方案。 我需要使用闭包来实现观察者模式,以避免协议,从而将观察者与观察者解耦。 观察者是一个像这样的闭包数组的对象: 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