【问题标题】:UITableview does not respond while loading data from firebase从 firebase 加载数据时 UITableview 没有响应
【发布时间】:2019-02-13 18:27:16
【问题描述】:

当我的 Tableview 开始从 firebase 加载数据时,它不会响应任何触摸。 (它已经显示了单元格,但没有反应)一段时间后,它会在表格视图没有反应时进行您尝试执行的滚动。

var filteredData = [archivCellStruct]()
func firData() {
filteredData.removeAll()
 var databaseRef : DatabaseReference!

    databaseRef = Database.database().reference()

databaseRef.child("Aufträge").child("Archiv").queryOrderedByKey().observe(.childAdded, with:{
        snapshot in
        let snap = snapshot.value as? NSDictionary

        //extracting the data and appending it to an Array
            self.filteredData.append(//myData)
            self.tableView.reloadData()

    })
}

所以它适用于少量数据(tableview 行)但延迟很大(我已经在过滤数据以限制 tableView 中显示的数据)。 我认为它与 tableView.reloadData() 有关(也许用户交互在重新加载时被禁用?)

【问题讨论】:

  • 能否提供周边代码?我怀疑您正在导致阻塞的主线程上加载数据。

标签: ios swift uitableview firebase reload


【解决方案1】:

每次你必须异步重新加载你的 tableview -

var filteredData = [archivCellStruct]()
func firData() {
filteredData.removeAll()
 var databaseRef : DatabaseReference!

    databaseRef = Database.database().reference()

databaseRef.child("Aufträge").child("Archiv").queryOrderedByKey().observe(.childAdded, with:{
        snapshot in
        let snap = snapshot.value as? NSDictionary

        //extracting the data and appending it to an Array
            self.filteredData.append(//myData)

            DispatchQueue.main.async {      //change this in you code
            self.tableView.reloadData()
            }

    })
} 

【讨论】:

  • 然后将 .childadded 更改为 .value 如果在观察方法中不起作用,这可能会起作用
  • 所以我现在停止了时间。它在 1 秒内接收到全部数据。对于异步执行,表视图需要 32 秒才能响应。如果没有异步执行,则需要 40 秒。
【解决方案2】:

使用 firebase,您可以手动操作:

用例:

struct UseCaseName {
     struct Request {}
     struct Response {
         let firebaseCallbackData: [FirebaseModelType]
     }
     struct ViewModel {
         let data: [DisplayType]
     }
}

视图控制器:

var filteredData: [DisplayType]! = []
override func viewWillAppear() {
    // this one can make you trouble, adjust the observation logic to whatever you need. `WillAppear` can fire multiple times during the view lifecycle
    super.viewWillAppear()
    interractor?.observe()
}

func showData(viewModel: Scene.Usecase.ViewModel) {
    // this is where the different approach begins
    tableView.beginUpdates()
    var indexPaths = [NSIndexPath]()
    for row in (filteredData.count..<(FilteredData.count + viewModel.data.count)) {
        indexPaths.append(NSIndexPath(forRow: row, inSection: 0))
    }

    filteredData += viewModel.data

    tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
    tableView.endUpdates()
}

交互者:

func observe(request: Scene.UseCase.Request) { /* signup for updates with observe(_ eventType: DataEventType, with block: @escaping (DataSnapshot) -> Void) -> UInt */
     callback is something like { DataSnapshot in presenter.presentData(response: Scene.Usecase.Response())
}

演讲者:

func presentData(response: Scene.UseCase.Response) {
    /* format for representation */
    DispatchQueue.main.async {
        controller.present(viewModel: Scene.UseCase.ViewModel())
    }
}

对不起,分流,我已经沉迷于这种方式了。 另外我假设,firebase 中的数据没有被修改,而是被添加(因为observe(.childAdded, 部分。如果我错了,请编辑你的问题以反映这一点。另一个假设是你有一个部分。不要忘记将inSection: 0 更改为适当的部分。我很懒,所以对移动设备不太友好 这种方式只会附加 Firebase 发送的新值,工作速度更快

编辑:另一个答案。

DispatchQueue.main.async { //change this in you code self.tableView.reloadData() }

有时重新加载所有项目并不好。然而,这取决于计数。如果我的假设是正确的,最好在不重新加载整个表格的情况下更新单独的单元格。快速示例:类似于与 Firebase“后端”的聊天。解释:无论如何,添加一行会比 reloadData() 更快,但只有当你经常调用这些方法时,差异才会很大。对于聊天示例,如果聊天是垃圾邮件,则差异可能足够大,以优化控制器中的 UITableView 重新加载行为。

还很高兴看到影响方法的代码。这可能是线程问题,就像 John Ayers 在 cmets 中所说的那样。你在哪里打电话func firData()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多