这本书说“函数和闭包都是引用类型”,那么如何判断它们的引用是否相等呢? == 和 === 并不起作用。
func a() { }
let å = a
let b = å === å // Could not find an overload for === that accepts the supplied arguments
这本书说“函数和闭包都是引用类型”,那么如何判断它们的引用是否相等呢? == 和 === 并不起作用。
func a() { }
let å = a
let b = å === å // Could not find an overload for === that accepts the supplied arguments
我知道我回答这个问题已经晚了六年,但我认为看一下问题背后的动机是值得的。提问者评论道:
如果不能通过引用从调用列表中删除闭包,那么我们需要创建自己的包装器类。这很麻烦,也不应该是必须的。
所以我猜这位提问者想要维护一个回调列表,像这样:
class CallbackList {
private var callbacks: [() -> ()] = []
func call() {
callbacks.forEach { $0() }
}
func addCallback(_ callback: @escaping () -> ()) {
callbacks.append(callback)
}
func removeCallback(_ callback: @escaping () -> ()) {
callbacks.removeAll(where: { $0 == callback })
}
}
但是我们不能这样写removeCallback
,因为==
对于函数不起作用(===
也不行)。
以下是另一种管理回调列表的方法。从addCallback
返回一个注册对象,并使用该注册对象来删除回调。在2020年,我们可以使用Combine的AnyCancellable
作为注册对象。
修改后的API如下:
class CallbackList {
private var callbacks: [NSObject: () -> ()] = [:]
func call() {
callbacks.values.forEach { $0() }
}
func addCallback(_ callback: @escaping () -> ()) -> AnyCancellable {
let key = NSObject()
callbacks[key] = callback
return .init { self.callbacks.removeValue(forKey: key) }
}
}
removeCallback
。没有removeCallback
方法。相反,您保存AnyCancellable
,并调用其cancel
方法来删除回调。更好的是,如果您将AnyCancellable
存储在实例属性中,则在销毁实例时它将自动取消。
MyClass.self
)的相等性。 - Jiaaroå
上使用变音符号来引用a
的用法真的很有趣。你在这里探索的是一种约定吗?(我不知道我是否真的喜欢它;但它似乎非常强大,特别是在纯函数式编程中。) - Rob Napier