我正在尝试仅使用函数在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模式有任何更好的想法吗? (我不想使用协议)
答案 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
捕获为unowed
或weak
。
以下文章详细介绍了此解决方案:https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b#.dmijmxbc4