2017-08-28 95 views
2

我有一个函数返回一个类对象或零。该功能的目的是检查是否存在Chat。聊天ID存储在MySQL中。如果ID存在,我执行Firebase引用来获取快照,然后获取对象。如果ID不存在,我返回nil:void函数中意外的非void返回值Swift3

func findChat(string: String) -> Chat? { 

    var returnValue: (Chat?) 
    let url = getChatsURL 
    let Parameters = [ "title" : string ] 

    Alamofire.request("\(url)", method: .post, parameters: Parameters).validate().responseString { response in 
      if let anyResponse = response.result.value { 
       self.responseFromServer = anyResponse 
      } 

      if self.responseFromServer == "" { 
       returnValue = nil 
      } else { 
       let ref = DatabaseReference.chats.reference() 
       let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: (self.responseFromServer)) 
       query.observe(.childAdded, with: { snapshot in 
       returnValue = Chat(dictionary: snapshot.value as! [String : Any]) 
      }) 
     } 
     return returnValue 
    } 

} 

然而,在return returnValue我越来越空隙功能

意外的非空返回值。

想到我可能会错过的任何想法?

+0

类似[这个问题](https://stackoverflow.com/a/32121273/6541007)。 – OOPer

回答

2

问题是你试图从一个闭包中返回一个非void值,它只能从闭包中返回,但由于该闭包需要一个void返回值,所以会收到错误。

您不能从使用标准return ...语法异步函数返回,你必须声明你的函数接受完成处理程序和完成处理内部的异步网络调用返回的值。

func findChat(string: String, completion: @escaping (Chat?)->()) { 
    var returnValue: (Chat?) 
    let url = getChatsURL 
    let Parameters = [ "title" : string ] 

    Alamofire.request("\(url)", method: .post, parameters: Parameters).validate().responseString { response in 
     if let anyResponse = response.result.value { 
      self.responseFromServer = anyResponse 
     } 
     if self.responseFromServer == "" { 
      completion(nil) 
     } else { 
      let ref = DatabaseReference.chats.reference() 
      let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: (self.responseFromServer)) 
       query.observe(.childAdded, with: { snapshot in 
       completion(Chat(dictionary: snapshot.value as! [String : Any])) 
      }) 
     } 
    } 
} 

然后你就可以调用这个函数,并使用返回值是这样的:

findChat(string: "inputString", completion: { chat in 
    if let chat = chat { 
     //use the return value 
    } else { 
     //handle nil response 
    } 
}) 
+1

哇!非常感谢你。该解决方案完美运作。我将需要学习更多的东西来理解为什么! – Sente

+0

很高兴我能帮到你。如果您想了解更多关于该主题的内容,请查看异步函数和完成处理程序(如果您非常热衷,即使通常关闭,完成处理程序实际上也是关闭)。 –

2

你的块是异步执行的,但你试图从封闭函数中返回一个值。它不这样工作。你的findChat函数需要自己完成一个完成块,而不是返回一个值,然后你可以从你试图说return returnValue的地方调用完成块。