无法调用非函数类型“任何?!”的值:- Firebase,Swift3

Posted

技术标签:

【中文标题】无法调用非函数类型“任何?!”的值:- Firebase,Swift3【英文标题】:Cannot call value of non-function type 'Any?!' :- Firebase,Swift3 【发布时间】:2016-09-17 20:22:59 【问题描述】:

这是我迁移到 Swift 3 之前的代码:

ref.observeEventType(.ChildAdded, withBlock:  snapshot in
            let currentData = snapshot.value!.objectForKey("Dogs")
            if currentData != nil 
            let mylat = (currentData!["latitude"])! as! [String]
            let mylat2 = Double((mylat[0]))
            let mylon = (currentData!["longitude"])! as! [String]
            let mylon2 = Double((mylon[0]))
            let userid = (currentData!["User"])! as! [String]
            let userid2 = userid[0]
            let otherloc = CLLocation(latitude: mylat2!, longitude: mylon2!)
            self.distanceBetweenTwoLocations(self.currentLocation, destination: otherloc, userid: userid2)
            
        )

这是我迁移到 Swift 3 之后的代码:

ref.observe(.childAdded, with:  snapshot in
            let currentData = (snapshot.value! as AnyObject).object("Dogs")
            if currentData != nil 
                let mylat = (currentData!["latitude"])! as! [String]
                let mylat2 = Double((mylat[0]))
                let mylon = (currentData!["longitude"])! as! [String]
                let mylon2 = Double((mylon[0]))
                let userid = (currentData!["User"])! as! [String]
                let userid2 = userid[0]
                let otherloc = CLLocation(latitude: mylat2!, longitude: mylon2!)
                self.distanceBetweenTwoLocations(self.currentLocation, destination: otherloc, userid: userid2)
            
        )

然后我在第二行得到一个错误:

不能调用非函数类型'Any?!'的值

我唯一尝试的是将第二行更改为以下代码:

snapshot.value as! [String:AnyObject]

但这是不对的,其中没有包含“Dogs”,它警告我distanceBetweenTwoLocations 代码从未使用过。

【问题讨论】:

【参考方案1】:

看到问题是,当您实例化和初始化变量时,您告诉它它将接收到的值将是 value 用于此快照中名为 Dogs 的对象其类型为AnyObject

但是 snapshot.value 是字典类型,即[String:AnyObject],NSDictionary..

您检索的Dogs 节点的类型是字典或数组。

基本上,您应该避免将值存储在 AnyObject 类型的变量中

试试这个:-

      FIRDatabase.database().reference().child("Posts").child("post1").observe(.childAdded, with:  snapshot in
        if let currentData = (snapshot.value! as! NSDictionary).object(forKey: "Dogs") as? [String:AnyObject]

            let mylat = (currentData["latitude"])! as! [String]
            let mylat2 = Double((mylat[0]))
            let mylon = (currentData["longitude"])! as! [String]
            let mylon2 = Double((mylon[0]))
            let userid = (currentData["User"])! as! [String]
            let userid2 = userid[0]
            let otherloc = CLLocation(latitude: mylat2!, longitude: mylon2!)
            self.distanceBetweenTwoLocations(self.currentLocation, destination: otherloc, userid: userid2)
        
    )

PS:-看到您的 JSON 结构,您可能想将其转换为字典而不是数组

【讨论】:

我在 if 行中收到警告:Comparing non-optional value of type '[String : AnyObject]' to nil always returns true 以及我在问题中写的distanceBetweenTwoLocations 中的警告。 我已经更新了我的答案。至于 distanceBetweenTwoLocations 我不能说话,因为我看不到你的代码中写了什么.. 现在它通过 currentData (在我删除 child("Posts").child("post1") 之后。但由于某种原因仍然在 distanceBetweenTwoLocations 中收到警告,在迁移到 Swift 3 之前我没有这个问题 distanceBetweenTwoLocations 是什么,你在哪里声明的。如果没有更多信息,无法为您提供帮助.. 是的,它帮助了我,而且是正确的!非常感谢你!显然,由于 Firebase 身份验证连接,distanceBetweenTwoLocations 不起作用。如果您想提供帮助,我在这里提出了新问题:):***.com/questions/39556586/…【参考方案2】:

在 Swift 3 中,AnyObject 已更改为 Any,这实际上可以是任何东西。 尤其是在使用键和索引下标时,现在需要告诉编译器实际类型。

解决方案是将 snapshot.value 转换为 Swift 字典类型 [String:Any] 。可选绑定安全地展开值

if let snapshotValue = snapshot.value as? [String:Any], 
   let currentData = snapshotValue["Dogs"] as? [String:Any] 

     let mylat = currentData["latitude"] as! [String]
     ...

您使用的感叹号过多。 latitude"] 之后的标记在 as! 之前不需要并且始终使用 if let 而不是检查 nil

【讨论】:

到目前为止还不错,但在 distanceBetweenTwoLocations 行代码中我收到警告:Result of call to 'distanceBetweenTwoLocations(_:destination:userid:)' is unused。正如它警告我的那样 - 由于某种原因,它从未使用过(它在更改为 Swift 3 之前使用过)。 在不使用结果的情况下调用方法进行计算是荒谬的。 您在 Swift 3 之前的代码也不使用结果。在 Swift 3 中,您会收到更多关于未使用结果的警告,您可以将 @discardableResult 放在函数前面,或者如果根本不使用结果,则删除结果类型。 不可能!它工作得很好!它显示了该位置之间的所有用户,更改为 swift 3 后没有任何反应。 @discardableResult 是什么? 获得currentData 的可选绑定是否通过了? @discardableResult 抑制 unused result 警告。【参考方案3】:

我还有一个代码片段,它允许您访问子节点的值。希望对您有所帮助:

if let snapDict = snapShot.value as? [String:AnyObject] 

            for child in snapDict

                if let name = child.value as? [String:AnyObject]

                    var _name = name["locationName"]
                    print(_name)
                

            

        

最好的问候, 纳扎尔·梅德罗斯

【讨论】:

以上是关于无法调用非函数类型“任何?!”的值:- Firebase,Swift3的主要内容,如果未能解决你的问题,请参考以下文章

无法调用非函数类型“URL”的值

无法调用非函数类型 HTTPURLResponse 的值?

错误:无法调用非函数类型的值

Swift 3 错误“无法调用非函数类型 'UITableView!' 的值” [关闭]

无法调用非函数类型“HTTPURLResponse?”的值

Alamofire:无法调用非函数类型“NSHTTPURLResponse”的值?