我在带有 Swift 3 的 iOS 上使用 Firebase。
当我使用
FIRDatabase.database().reference().child("child").setValue("value") {
(error: Error?, databaseReference: FIRDatabaseReference) in
print("Error while setting value \(error)")
}
应用程序在运行时崩溃并显示以下日志:
*** Terminating app due to uncaught exception 'InvalidFirebaseData', reason: '(nodeFrom:priority:) Cannot store object of type _SwiftValue at . Can only store objects of type NSNumber, NSString, NSDictionary, and NSArray.'
我尝试使用相同的函数,但没有尾随闭包,出于某种原因,它起作用了!
FIRDatabase.database().reference().child("child").setValue("value",
withCompletionBlock: {
(error: Error?, databaseReference: FIRDatabaseReference) in
print("Error while setting value \(error)")
})
尾随闭包和 Swift 3 有什么特别之处吗?
最佳答案
tl;dr:Firebase 提供了一个 setValue(_ value: Any?, andPriority priority: Any?)
,当使用带有 setValue(_值:Any?, withCompletionBlock: (Error?, FIRDatabaseReference) -> Void)
。
解决方案:当使用具有多种变体的 API 时,避免使用尾随闭包。在这种情况下,更喜欢 setValue(myValue, withCompletionBlock: { (error, dbref) in/* ... */})
;不要不使用setValue(myValue) { (error, dbref) in/* ... */
。
解释
这似乎是一个 Swift 错误。与其他语言(如 Java)一样,Swift 通常会选择最具体的重载。例如,
class Alpha {}
class Beta : Alpha {}
class Charlie {
func charlie(a: Alpha) {
print("\(#function)Alpha")
}
func charlie(a: Beta) {
print("\(#function)Beta")
}
}
Charlie().charlie(a: Alpha()) // outputs: charlie(a:)Alpha
Charlie().charlie(a: Beta() as Alpha) // outputs: charlie(a:)Alpha
Charlie().charlie(a: Beta()) // outputs: charlie(a:)Beta
然而,当重载函数匹配尾随闭包时,Swift(至少,有时)会选择更通用的类型。例如,
class Foo {
func foo(completion: () -> Void) {
print(#function)
}
func foo(any: Any?) {
print(#function)
}
}
func bar() {}
Foo().foo(completion: bar) // outputs: foo(completion:)
Foo().foo(any: bar) // outputs: foo(any:)
Foo().foo() { () in } // outputs: foo(any:)
// ^---- Here lies the problem
// Foo().foo(bar) will not compile; can't choose between overrides.
Any?
是比 () -> Void
更通用的类型——也就是说,“任何东西,甚至是 null”比“接收 0 个参数的函数”更广泛并返回 Void
类型的内容”。但是,尾随闭包匹配 Any?
;这与您对匹配最特定类型的语言的期望相反。
关于ios - Firebase Swift 3 数据库在 setValue withCompletionBlock 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41406567/