闭包不能隐式捕获变异的自身参数
我正在使用Firebase观察事件,然后在完成处理程序中设置图像
FirebaseRef.observeSingleEvent(of: .value, with: { (snapshot) in if let _ = snapshot.value as? NSNull {
self.img = UIImage(named:"Some-image")!
} else {
self.img = UIImage(named: "some-other-image")!
}
})
但是我收到此错误
闭包不能隐式捕获变异的自身参数
我不确定这个错误是什么,寻找解决方案并没有帮助
回答:
拥有您的调用的类型FirebaseRef.observeSingleEvent(of:with:)
很可能是值类型(a
struct
?),在这种情况下,变异上下文可能不会self
在@escaping
闭包中显式捕获。
一种简单的解决方案是将您的拥有类型更新为一次引用(class
)。
observeSingleEvent(of:with:)
Firebase的方法声明如下
func observeSingleEvent(of eventType: FIRDataEventType,
with block: @escaping (FIRDataSnapshot) -> Void)
所述block
封闭件标有@escaping
参数属性,这意味着它可逃脱其功能的身体,并且甚至寿命self
(在上下文)。利用这些知识,我们构建了一个更简单的示例,我们可以对其进行分析:
struct Foo { private func bar(with block: @escaping () -> ()) { block() }
mutating func bax() {
bar { print(self) } // this closure may outlive 'self'
/* error: closure cannot implicitly capture a
mutating self parameter */
}
}
现在,错误消息变得更具说服力了,我们转向在Swift 3中实现的以下演进建议:
- SE-0035:将inout捕获限制为
@noescape
上下文
说明[强调我的]:
捕获
inout
参数()会成为可逃逸的闭包文字中的错误。 *
现在,这是关键点。对于一个 值
类型(例如struct
),我相信observeSingleEvent(...)
在您的示例中拥有该调用的类型也是这种情况,因此无法进行显式捕获,即afaik(因为我们正在使用值类型,而不是引用)之一)。
解决此问题的最简单方法是使拥有observeSingleEvent(...)
引用类型的类型成为引用类型,例如a class
,而不是a
struct
:
class Foo { init() {}
private func bar(with block: @escaping () -> ()) { block() }
func bax() {
bar { print(self) }
}
}
请注意,这将self
被强大的参考所捕获;根据您的上下文(我自己没有使用过Firebase,所以我不知道),您可能想显式地捕获self
弱点,例如
FirebaseRef.observeSingleEvent(of: .value, with: { [weak self] (snapshot) in ...
以上是 闭包不能隐式捕获变异的自身参数 的全部内容, 来源链接: utcz.com/qa/411149.html