Firebase Swift 3数据库在setValue withCompletionBlock上崩溃 [英] Firebase Swift 3 Database crashes on setValue withCompletionBlock
问题描述
当我使用
<在
中打印(code> FIRDatabase.database()。reference()。child(child).setValue(value){
(error:Error ?, databaseReference:FIRDatabaseReference) 设置值时出错\(错误))
}
应用程序崩溃运行时使用以下日志:
$ b
***由于未捕获异常InvalidFirebaseData,终止应用程序,原因:'(nodeFrom:priority :)无法存储_SwiftValue
类型的对象。只能存储类型为NSNumber,NSString,NSDictionary,
和NSArray的对象。'
我尝试使用相同的函数但是没有尾随的关闭,出于某种原因,它是有效的!
FIRDatabase.database()。reference()。child( (错误)设置值时出错(错误))
print(Errorwhile setting value \(error))
))
关于尾随闭包和Swift 3有什么特别之处吗?
tl; dr:Firebase提供了一个 setValue(_ value:Any ?,和优先级优先级:任何? )
与 setValue(_ value:Any?,withCompletionBlock:(Error?,FIRDatabaseReference) - > Void) c>。
解决方案:使用多种类型的API时,追尾关闭。在这种情况下,首选 解释 这似乎是一个Swift错误。和其他语言一样,Swift通常会选择最具体的过载。例如, I am using Firebase on iOS with Swift 3. When I use The app crashes on runtime with the following log: *** 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.' I tried to use the same function but without the trailing closure and for some reason, it works! Is there something special about trailing closures and Swift 3? tl;dr: Firebase provides a Solution: When using an API that has many varieties, avoid using trailing closures. In this case, prefer Explanation This appears to be a Swift bug. As in other languages, such as Java, Swift generally chooses the most specific overload. E.g., However, when overloaded functions match a trailing closure, Swift (at least, sometimes) selects the more general type. E.g., 这篇关于Firebase Swift 3数据库在setValue withCompletionBlock上崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! setValue(myValue,withCompletionBlock:{(error,dbref)in / * ... * /})
;在/ * ... * /} 中使用 setValue(myValue){(error,dbref)来执行 。 b
class Alpha {}
class Beta:Alpha {}
class Charlie {
func charlie(a:Alpha){
print(\(#function)Alpha)
}
func charlie(a:Beta){
print(\(#function)Beta)
}
}
charlie(a:Alpha())//输出:charlie(a: )char $(a:Beta())//输出:charlie():char $(char)然而,当重载函数匹配结尾的闭包时,Swift(至少,它是一个函数)有时)选择更一般的类型。例如,
class Foo {
func foo(completion:() - > Void){
print(#function)
}
func foo(any:Any?){
print(#function)
}
}
func bar(){}
Foo().foo(completion:bar)//输出:foo(完成:)
Foo().foo(any:bar)// outputs:foo(any :)
Foo()。foo(){()in} //输出:foo(any :)
// ^ ----这就是问题
// Foo ).foo(bar)不会编译;无法在覆盖之间进行选择。
任何?
() - > Void
- 即nothing,even null比接收0个参数并返回类型 Void
>的函数更广泛。但是,结尾匹配符合 Any?
;这与你所期望的与最具体类型匹配的语言是相反的。FIRDatabase.database().reference().child("child").setValue("value") {
(error: Error?, databaseReference: FIRDatabaseReference) in
print("Error while setting value \(error)")
}
FIRDatabase.database().reference().child("child").setValue("value",
withCompletionBlock: {
(error: Error?, databaseReference: FIRDatabaseReference) in
print("Error while setting value \(error)")
})
setValue(_ value: Any?, andPriority priority: Any?)
which is incorrectly matched when using a trailing closure with setValue(_ value: Any?, withCompletionBlock: (Error?, FIRDatabaseReference) -> Void)
.setValue(myValue, withCompletionBlock: { (error, dbref) in /* ... */ })
; do not use setValue(myValue) { (error, dbref) in /* ... */ }
.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
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?
is a more general type than () -> Void
-- i.e., "anything, even null" is more broad than "a function receiving 0 parameters and returning something of type Void
". However, the trailing closure matches Any?
; this is the opposite of what you would expect from a language that matches the most specific type.