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
捕获为 unowed
或 weak
.
这是一篇更详细地解释这个解决方案的文章:https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b#.dmijmxbc4
我试图在 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
捕获为 unowed
或 weak
.
这是一篇更详细地解释这个解决方案的文章:https://medium.cobeisfresh.com/why-you-shouldn-t-use-delegates-in-swift-7ef808a7f16b#.dmijmxbc4