The short version个
您拨打FirebaseRef.observeSingleEvent(of:with:)
的电话类型很可能是值类型(a struct
?),在这种情况下,变异上下文可能不会在@escaping
闭包中显式捕获self
.
简单的解决方案是将您拥有的类型更新为引用一次(class
).
The longer version个
第observeSingleEvent(of:with:)
method of 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中实施的以下演进方案:
陈述[强调我的]:
捕获inout
参数including 101 in a mutating
method变成可回避闭包文字unless the
capture is made explicit中的错误(因此是不可变的).
现在,这是一个关键点.对于value类型(例如struct
),我相信在您的示例中拥有observeSingleEvent(...)
调用的类型也是如此,这样的显式捕获是不可能的,因为我们使用的是值类型,而不是引用类型.
此问题的最简单解决方案是将拥有observeSingleEvent(...)
的类型设置为引用类型,例如class
,而不是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 ...