【问题标题】:I've got a Unexpected non-void return value in void function error?我在 void 函数错误中有一个 Unexpected non-void return value?
【发布时间】:2018-12-25 02:30:54
【问题描述】:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    switch section {
    case 0:

var 语句的重新声明

        one = Database.database().reference()

从数据库中收集信息

        one.child("users").child("profile").observe(.value, with: {(snapshot) in
            let num = snapshot.childrenCount

出错的地方

            return Int(num)
        })
    default:
        return 0
    }

}

【问题讨论】:

  • 一般来说,您不能从 Firebase 闭包返回值,因为它们不是函数,并且尝试直接从 Firebase(通过互联网)维护 tableView 会很慢。见下文 cmets。
  • 您确定要读取/users/profile 中的所有 个节点吗?通常是 /users/uid/profile 来获取单个用户的数据。

标签: swift firebase firebase-realtime-database switch-statement


【解决方案1】:

您传递给观察的这个函数被键入为返回 void 的函数:

{(snapshot) in
    let num = snapshot.childrenCount
    return Int(num)
})

您可以从observe 的 API 文档中看到:

声明

func observe(_ eventType: DataEventType, with block: @escaping (DataSnapshot) -> Void) -> UInt

函数的类型是(DataSnapshot) -> Void,表示它不能返回值。但是你却返回了Int(num)

您将无法从 collectionView() 返回数据库查询的结果,因为数据库观察者是异步的并且会立即返回。一段时间后它会给你一个值,你无法保证需要多长时间。

【讨论】:

    【解决方案2】:

    道格·史蒂文森是对的!

    您可以做的是在从服务器获取数据后,对其进行解析并将其保存到变量并更新您的 collectionView。

    var data = [YourModel]()
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return data.count
    }
    
    Database.database().reference().child("users").child("profile").observe(.value, with: {(snapshot) in
    
        let values = snapshot.values as? [String: Any] else { return }
    
        var tmpArrayOfValues = [YourModel]()
    
        // here you create YourModel objects
        values.forEach { (item) in
            let newItem = //create your item from values
            tmpArrayOfValues.append(newItem)
        }    
    
        self.data = tmpArrayOfValues
    
        // to update UI you have to return to main thread, because firebase func are running on background thread
        DispatchQueue.main.async {
            self.collectionView.reloadData()
        }
    }
    

    【讨论】:

    • 请注意,不需要 DispatchQueue,因为 Firebase 闭包中的 UI 调用是在主线程上执行的,并且没有理由填充 tempArray - 可以直接填充类级别的 self.data 数组。您可能希望将此代码调整为 .observeSingleEvent ,因为 .value 在节点上留下一个观察者以观察变化,而 OP 似乎只想得到它一次。
    猜你喜欢
    • 2014-09-17
    • 1970-01-01
    • 2021-12-18
    • 2021-04-18
    • 2020-01-18
    • 2017-12-04
    • 2023-01-28
    • 2020-11-18
    相关资源
    最近更新 更多