为什么我不能将捕获列表添加到闭包 属性?
Why can't I add a capture list to a closure property?
在我的代码中,我调用了一些采用闭包的方法。我每次都通过完全相同的闭包。所以我决定将闭包提取为 属性。并在我每次调用这些方法时传递 属性。这样可以大大减少重复代码。
但是,当我尝试将捕获列表 [weak self]
添加到闭包 属性 时,编译器不允许我这样做!
'weak' may only be applied to class and class-bound protocol types, not '<<error type>>'
我不知道那是什么意思。
MCVE:
class A {
var num = 0
let closure: (Int) -> Void = {
[weak self] x in
self?.num += x
}
init() {
let b = B()
b.doStuff {
[weak self] x in
self?.num += x
}
}
}
class B {
var stuff: ((Int) -> Void)!
func doStuff(stuff: (Int) -> Void) {
self.stuff = stuff
}
}
在classA
的init
中,我用闭包调用了doStuff
。在该闭包中,捕获列表起作用。但是当我将闭包声明为 属性(第 4 - 7 行)时,捕获列表不起作用。
这是否意味着闭包属性不持有对 self
的强引用并且具有隐式 [unowned self]
捕获列表?但这对我来说意义不大...
Class/Struct 属性通常在 before init()
方法被调用之前初始化,因此 before 实例是适当分配。因此,属性 中的捕获无效,self
尚未初始化。
你仍然可以通过延迟初始化 属性:
lazy var closure: (Int) -> Void = {
[weak self] x in
self?.num += x
}
这是有效的,因为惰性属性只能在 self
完全初始化时才能访问。
目前不可能有一个恒定的惰性 属性,但这可能会在未来改变。我知道的唯一解决方法是使用私有 setter:
private(set) lazy var closure: (Int) -> Void = {
[weak self] x in
self?.num += x
}
在我的代码中,我调用了一些采用闭包的方法。我每次都通过完全相同的闭包。所以我决定将闭包提取为 属性。并在我每次调用这些方法时传递 属性。这样可以大大减少重复代码。
但是,当我尝试将捕获列表 [weak self]
添加到闭包 属性 时,编译器不允许我这样做!
'weak' may only be applied to class and class-bound protocol types, not '<<error type>>'
我不知道那是什么意思。
MCVE:
class A {
var num = 0
let closure: (Int) -> Void = {
[weak self] x in
self?.num += x
}
init() {
let b = B()
b.doStuff {
[weak self] x in
self?.num += x
}
}
}
class B {
var stuff: ((Int) -> Void)!
func doStuff(stuff: (Int) -> Void) {
self.stuff = stuff
}
}
在classA
的init
中,我用闭包调用了doStuff
。在该闭包中,捕获列表起作用。但是当我将闭包声明为 属性(第 4 - 7 行)时,捕获列表不起作用。
这是否意味着闭包属性不持有对 self
的强引用并且具有隐式 [unowned self]
捕获列表?但这对我来说意义不大...
Class/Struct 属性通常在 before init()
方法被调用之前初始化,因此 before 实例是适当分配。因此,属性 中的捕获无效,self
尚未初始化。
你仍然可以通过延迟初始化 属性:
lazy var closure: (Int) -> Void = {
[weak self] x in
self?.num += x
}
这是有效的,因为惰性属性只能在 self
完全初始化时才能访问。
目前不可能有一个恒定的惰性 属性,但这可能会在未来改变。我知道的唯一解决方法是使用私有 setter:
private(set) lazy var closure: (Int) -> Void = {
[weak self] x in
self?.num += x
}